Friend Functions And Classes In C++

The friend keyword in C++ is one of those concepts that is formally taught, but then seems to disappear off the scene once you get into the real world. Maybe friends are less common in embedded programming (ha ha), but I’ve seen very few of them over the years.

The thing is, they just don’t seem to be at the forefront of people’s minds when writing code. When would you ever actually use one of these things?

Aren’t they just a way to avoid writing getters and setters??

I think when you are learning a language, understanding concrete examples of why a concept is there is absolutely necessary if that concept is to stick and be used well.

So let’s have a look at friend functions and classes and see what on earth we could do with them.

The official explanation – example 1

Declaring a function (or class), as a friend, means that the function (or class) can access the private area of that class’ declaration.

In all other ways, nothing else is different. The friendship is one way, limited only to the class in which you add it, and has no other effect on either class/method involved (including sub classes, base classes and other friend classes). It defines a single relationship.

So, we can assign any old class, or function, in our code base, to be a friend of another class, by adding it to the declaration of that other class with the friend keyword. Let’s see that in code, so we are certain we know what’s going on.

Here’s our class:

class Rectangle
{
public:
    //constructor, destructor and all that jazz
    friend class Puzzle;
    friend float CalculateArea();
private:
    //rectangle's private data
};

class Puzzle
{
    //normal class stuff
};

float CalculateArea()
{
    //do some fancy calculations
    //return result
}

OK, so this is a contrived example (as they always are), but bear with me. We’ll get to changing that in a minute.

For now, let’s just look at the way we use the keyword.

We’ve got an ordinary class (Puzzle), and an ordinary function (CalculateArea), and both have been added to the Rectangle class declaration as friends.

Now Puzzle and CalculateArea can access Rectangle’s private data and private methods.

That’s all there is to it.

But why would you ever want to do this?

We all know that C++ is a powerful language that allows you to model the real world in terms of objects, and interactions between those objects.

Encapsulation is one of the big concepts in C++, a cornerstone of the language. It means that classes contain their own data, and methods to manipulate that data, independently of the other parts of the program.

So, on the surface, it may seem as if adding friend classes and functions goes against this idea: if you add friends to a class, they aren’t independently managing their own data anymore. Things could get messy!!

Not quite.

The thing is, in the real world, objects aren’t completely discrete items. Take even the contrived example above – a Puzzle class might be a friend of a Rectangle, a Square and a Polygon because it needs to calculate how to fit them into a predefined area.

You can’t use inheritance (a rectangle is a kind of puzzle? Nope), and templates are no good either.

Just imagine that collection of objects – rectangles, squares and crosses – all jiggling around trying to calculate their own position on the board. It wouldn’t work! A puzzle class however, can fit them together. But the Puzzle class needs to know all sorts of things about the objects it is positioning.

Instead of having to add identical calling methods for number of sides, side length, etc. to each shape, if you make the Puzzle class a friend of each shape, it can access the the private data that it needs and do the job neatly. It simplifies all the shape objects and keeps the puzzle workings in a separate class. Much better.

Actually, I said that was a contrived example, but it’s not too bad is it?

Example 2

class Message
{
public:
    //constructor, destructor, and all that jazz
    friend class MessageStats;
private:
    //message's private data
};

In this case, we’ve got a Message class with a friend class called MessageStats.

Let’s assume the Message class itself doesn’t always deliver a complete message. Maybe the transmission packet only has room for a certain number of bytes, and messages have to be reconstructed on arrival out of several Message objects.

By giving MessageStats direct access to the private data of Message, it can keep a tally of how many whole messages are received in a day, even though some of the objects it looks at will be individual parts of a single message.

MessageStats could also keep a tally of error messages received, or any other kind of message that you wanted to keep an eye on.

Again, instead of having to write methods to return all of this information to a non-friend class (because you would never make the private data public, right?), the MessageStats class can access it directly.

To the “public” (i.e. the rest of your code), there is the choice of interacting with Message or MessageStats, but the raw data is held in one place and untouchable by everything else.

Friends can simplify and reduce the amount of code that you need to write.

Example 3

Let’s look at one more before we finish up.

Friend classes are really handy if you have to delve into operator overloading. This is when you redefine how (for example) the multiplication operator works so that you can use it on your own objects.

Not clear?

Okay, imagine that you have two different classes that contain numeric data. One may store integers as an array, the other as a two dimensional array. You want to be able to multiply the data together (like matrix multiplication, if you are familiar with it).

If you create an overloaded “*” method, and include it as a friend of the two classes that you want to multiply together, the overloaded “*” method can access the private numerical data of each object, and you can write:

multiplied_object = object1 * object2;

The same goes for any operator that you want to tailor to your specific needs.

Say you want to print an object to stdout:

cout << yourobject << endl;

Create an overloaded << method, and then add it as a friend to your class – the new << method can access the private data directly to print it to your screen.

What about encapsulation?

As I said above, it might seem at first as though friends are entangling things, but that’s not the case. The C++ FAQ puts it beautifully in saying:

Try thinking of a friend function as part of the class’s public interface.

And this is exactly what you should do.

Visually, it might look a little like this:

 

|= Lots of other classes and code in the rest of your program =|    <- other code
|____Class____| |____Friend Class____| |____Friend function____|    <- interface
|--- data ----|                                                     <- private data


In a nutshell:

A friend is a way to contain similar methods and ideas that are outside the scope of the original class, but that are intrinsically reliant on that class’ data.


One Comment

  1. Trevor Hickey
    Posted 20 December 2014 at 13:38 | Permalink

    Wow, Ive always thought of friend functions as a bit of a hack and needed for operator overloading. Picturing it as an interface is much more clear, and I now see many more practical use cases for them.