Click here to Skip to main content
15,886,032 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.7K   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 
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 
Thanks Wink | ;-)

An entertaining mistake on my part!
Glad it was pointed out.
I write little programming guides for C, C++, GDB and Linux.
FayeWilliams.com

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.