Click here to Skip to main content
15,893,508 members
Articles / Programming Languages / C++

Friend Functions and Classes in C++

Rate me:
Please Sign up or sign in to vote.
4.48/5 (12 votes)
25 Nov 2014CPOL6 min read 24.8K   12   19
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:

C++
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 private data that it needs and does 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

C++
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:

C++
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:

C++
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder FayeWilliams.com
United Kingdom United Kingdom
Programming shouldn't be a black art. Code is creative and beautiful. I write little programming guides for C, C++, GDB and Linux.

FayeWilliams.com

Comments and Discussions

 
SuggestionMessage Closed Pin
5-Sep-20 21:12
Member 149315785-Sep-20 21:12 
SuggestionWhen to use or avoid friend Pin
Stefan_Lang2-Dec-14 21:36
Stefan_Lang2-Dec-14 21:36 
Let me start by saying that I'm generally very wary of friend, mainly because it breaks encapsulation. But also because you really need to know who can or should be a friend of your class at the time you design that class, and you should be aware that any be-friended class or method must be revisited every time you change your class implementation! (this is really a consequence of friend breaking encapsulation in the first place)

You should be aware that making another class (or function) a friend gives them access to all of your your private parts, now and forever - maybe spouse would have been a better keyword. Wink | ;)

That said I've found that there are rare cases where the concern about encapsulation is not an issue. One case is your third example: overloaded operators are closely related to the classes they are granted access to, and are really part of those class implementations. Encapsulation isn't sacrificed because access remains limited to the limited number of operators that you can sensibly overload.

Another example that you didn't mention: iterators to containers. The STL is full of container classes and corresponding iterator classes that are declared friend to the underlying container. The main reason for using friend here is that the container class and its corresponding iterator classes are strongly related and are developed together. Encapsulation is not sacrificed, because it's clear which classes belong together and internal data is not published outside the container+iterator group of classes.

I don't like your first example because there is no clear relation between a Rectangle and a Puzzle, and by the same argumentation you are making you could declare pretty much any other class using Rectangle a friend, breaking encapsulation. I see no reason not to provide accessors to the internal shape data, since other classes and functions will likewise want to know about them and you can't implement all of them in your Rectangle or other shape class.

Your second example looks more like an example of closely related classes, but I don't think there is any reason not to provide accessors to all the internal data of your Message class, obviating the need to use friend.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

GeneralRe: When to use or avoid friend Pin
Faye Williams2-Dec-14 22:22
professionalFaye Williams2-Dec-14 22:22 
GeneralRe: When to use or avoid friend Pin
Stefan_Lang3-Dec-14 1:41
Stefan_Lang3-Dec-14 1:41 
GeneralRe: When to use or avoid friend Pin
Faye Williams3-Dec-14 3:31
professionalFaye Williams3-Dec-14 3:31 
QuestionFriends are essential Pin
john morrison leon28-Nov-14 3:38
john morrison leon28-Nov-14 3:38 
GeneralMy vote of 2 Pin
Alexandru Lungu26-Nov-14 10:24
professionalAlexandru Lungu26-Nov-14 10:24 
GeneralGreat explaination! Pin
koothkeeper26-Nov-14 8:27
professionalkoothkeeper26-Nov-14 8:27 
GeneralRe: Great explaination! Pin
Faye Williams26-Nov-14 9:19
professionalFaye Williams26-Nov-14 9:19 
QuestionMy vote of 4 Pin
den2k8826-Nov-14 4:51
professionalden2k8826-Nov-14 4:51 
GeneralMy vote of 5 Pin
sprice8626-Nov-14 4:34
professionalsprice8626-Nov-14 4:34 
GeneralMy vote of 1 Pin
Alexandru Lungu26-Nov-14 3:02
professionalAlexandru Lungu26-Nov-14 3:02 
Question... the author has never written a C++ program in her life Pin
Alexandru Lungu26-Nov-14 3:01
professionalAlexandru Lungu26-Nov-14 3:01 
AnswerRe: ... the author has never written a C++ program in her life Pin
Faye Williams26-Nov-14 3:37
professionalFaye Williams26-Nov-14 3:37 
AnswerRe: ... the author has never written a C++ program in her life Pin
dwight1000026-Nov-14 8:23
dwight1000026-Nov-14 8:23 
GeneralRe: ... the author has never written a C++ program in her life Pin
Faye Williams26-Nov-14 9:16
professionalFaye Williams26-Nov-14 9:16 
SuggestionRe: ... the author has never written a C++ program in her life Pin
Alexandru Lungu26-Nov-14 10:23
professionalAlexandru Lungu26-Nov-14 10:23 
GeneralRe: ... the author has never written a C++ program in her life Pin
Faye Williams26-Nov-14 10:49
professionalFaye Williams26-Nov-14 10:49 
GeneralRe: ... the author has never written a C++ program in her life Pin
Alexandru Lungu26-Nov-14 21:04
professionalAlexandru Lungu26-Nov-14 21:04 
GeneralRe: ... the author has never written a C++ program in her life Pin
Stefan_Lang3-Dec-14 2:08
Stefan_Lang3-Dec-14 2:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.