8.13 — Friend functions and classes

For much of this chapter, we’ve been preaching the virtues of keeping your data private. However, you may occasionally find situations where you will find you have classes and functions outside of those classes that need to work very closely together. For example, you might have a class that stores data, and a function (or another class) that displays the data on the screen. Although the storage class and display code have been separated for easier maintenance, the display code is really intimately tied to the details of the storage class. Consequently, there isn’t much to gain by hiding the storage classes details from the display code.

In situations like this, there are two options:
1) Have the display code use the publicly exposed functions of the storage class. However, this has several potential downsides. First, these public member functions have to be defined, which takes time, and can clutter up the interface of the storage class. Second, the storage class may have to expose functions for the display code that it doesn’t really want accessible to anybody else. There is no way to say “this function is meant to be used by the display class only”.

2) Alternatively, using friend classes and friend functions, you can give your display code access to the private details of the storage class. This lets the display code directly access all the private members and functions of the storage class, while keeping everyone else out! In this lesson, we’ll take a closer look at how this is done.

Friend functions

A friend function is a function that can access the private members of a class as though it were a member of that class. In all other regards, the friend function is just like a normal function. A friend function may be either a normal function, or a member function of another class. To declare a friend function, simply use the friend keyword in front of the prototype of the function you wish to be a friend of the class. It does not matter whether you declare the friend function in the private or public section of the class.

Here’s an example of using a friend function:

In this example, we’ve declared a function named reset() that takes an object of class Accumulator, and sets the value of m_value to 0. Because reset() is not a member of the Accumulator class, normally reset() would not be able to access the private members of Accumulator. However, because Accumulator has specifically declared this reset() function to be a friend of the class, the reset() function is given access to the private members of Accumulator.

Note that we have to pass an Accumulator object to reset(). This is because reset() is not a member function. It does not have a *this pointer, nor does it have an Accumulator object to work with, unless given one.

Here’s another example:

In this example, we declare the isEqual() function to be a friend of the Value class. isEqual() takes two Value objects as parameters. Because isEqual() is a friend of the Value class, it can access the private members of all Value objects. In this case, it uses that access to do a comparison on the two objects, and returns true if they are equal.

While both of the above examples are fairly contrived, the latter example is very similar to cases we’ll encounter in chapter 9 when we discuss operator overloading!

Multiple friends

A function can be a friend of more than one class at the same time. For example, consider the following example:

There are two things worth noting about this example. First, because PrintWeather is a friend of both classes, it can access the private data from objects of both classes. Second, note the following line at the top of the example:

This is a class prototype that tells the compiler that we are going to define a class called Humidity in the future. Without this line, the compiler would tell us it doesn’t know what a Humidity is when parsing the prototype for PrintWeather() inside the Temperature class. Class prototypes serve the same role as function prototypes -- they tell the compiler what something looks like so it can be used now and defined later. However, unlike functions, classes have no return types or parameters, so class prototypes are always simply class ClassName, where ClassName is the name of the class.

Friend classes

It is also possible to make an entire class a friend of another class. This gives all of the members of the friend class access to the private members of the other class. Here is an example:

Because the Display class is a friend of Storage, any of Display’s members that use a Storage class object can access the private members of Storage directly. This program produces the following result:

6.7 5

A few additional notes on friend classes. First, even though Display is a friend of Storage, Display has no direct access to the *this pointer of Storage objects. Second, just because Display is a friend of Storage, that does not mean Storage is also a friend of Display. If you want two classes to be friends of each other, both must declare the other as a friend. Finally, if class A is a friend of B, and B is a friend of C, that does not mean A is a friend of C.

Be careful when using friend functions and classes, because it allows the friend function or class to violate encapsulation. If the details of the class change, the details of the friend will also be forced to change. Consequently, limit your use of friend functions and classes to a minimum.

Friend member functions

Instead of making an entire class a friend, you can make a single member function a friend. This is done similarly to making a normal function a friend, except using the name of the member function with the className:: prefix included (e.g. Display::displayItem).

However, in actuality, this can be a little trickier than expected. Let’s convert the previous example to make Display::displayItem a friend member function. You might try something like this:

However, it turns out this won’t work. In order to make a member function a friend, the compiler has to have seen the full definition for the class of the friend member function (not just a forward declaration). Since class Storage hasn’t seen the full definition for class Display yet, the compiler will error at the point where we try to make the member function a friend.

Fortunately, this is easily resolved simply by moving the definition of class Display before the definition of class Storage.

However, we now have another problem. Because member function Display::displayItem() uses Storage as a reference parameter, and we just moved the definition of Storage below the definition of Display, the compiler will complain it doesn’t know what a Storage is. We can’t fix this one by rearranging the definition order, because then we’ll undo our previous fix.

Fortunately, this is also fixable in a couple of simple steps. First, we can add class Storage as a forward declaration. Second, we can move the definition of Display::displayItem() out of the class, after the full definition of Storage class.

Here’s what this looks like:

Now everything will compile properly: the forward declaration of class Storage is enough to satisfy the declaration of Display::displayItem() inside the Display class, the full definition of Display satisfies declaring Display::displayItem() as a friend of Storage, and the full definition of class Storage is enough to satisfy the definition of member function Display::displayItem(). If that’s a bit confusing, see the comments in the program above.

If this seems like a pain -- it is. Fortunately, this dance is only necessary because we’re trying to do everything in a single file. A better solution is to put each class definition in a separate header file, with the member function definitions in corresponding .cpp files. That way, all of the class definitions would have been visible immediately in the .cpp files, and no rearranging of classes or functions is necessary!


A friend function or class is a function or class that can access the private members of another class as though it were a member of that class. This allows the friend or class to work intimately with the other class, without making the other class expose its private members (e.g. via access functions).

Friending is uncommonly used when two or more classes need to work together in an intimate way, or much more commonly, when defining overloading operators (which we’ll cover in chapter 9).

Note that making a specific member function a friend requires the full definition for the class of the member function to have been seen first.

Quiz time

1) In geometry, a point is a position in space. We can define a point in 3d-space as the set of coordinates x, y, and z. For example, the Point(2.0, 1.0, 0.0) would be the point at coordinate space x=2.0, y=1.0, and z=0.0.

In physics, a vector is a quantity that has a magnitude (length) and a direction (but no position). We can define a vector in 3d-space as an x, y, and z value representing the direction of the vector along the x, y, and z axis (the length can be derived from these). For example, the Vector(2.0, 0.0, 0.0) would be a vector representing a direction along the positive x-axis (only), with length 2.0.

A Vector can be applied to a Point to move the Point to a new position. This is done by adding the vector’s direction to the point’s position to yield a new position. For example, Point(2.0, 1.0, 0.0) + Vector(2.0, 0.0, 0.0) would yield the point (4.0, 1.0, 0.0).

Points and Vectors are often used in computer graphics (the point to represent vertices of shape, and vectors represent movement of the shape).

Given the following program:

1a) Make Point3d a friend class of Vector3d, and implement function Point3d::moveByVector()

Show Solution

1b) Instead of making class Point3d a friend of class Vector3d, make member function Point3d::moveByVector a friend of class Vector3d.

Show Solution

1c) Reimplement the solution to quiz question 1b using 5 separate files: Point3d.h, Point3d.cpp, Vector3d.h, Vector3d.cpp, and main.cpp.

Thanks to reader Shiva for the suggestion and solution.

Show Solution

8.14 -- Anonymous objects
8.12 -- Static member functions

269 comments to 8.13 — Friend functions and classes

  • Anastasia

    In 'Friend member functions' Alex wrote: " ... A better solution is to put each class definition in a separate header file, with the member function definitions in corresponding .cpp files. That way, all of the class definitions would have been visible immediately in the .cpp files, and no rearranging of classes or functions is necessary!"
    Unfortunately not everything is so obvious with multiple files either. `Display.h` still wants a forward declaration of Storage, `Storage.h` needs `Display.h` included and we have to include both `Display.h` and `Storage.h` in `Display.cpp`. No rearranging of functions is necessary, but seems like pain nonetheless.

  • CuongLee

    Hi Alex,
    In file Point3d.h in 1c), why I can not #include"Vector3d.h" instead of declaring prototype vector3d? It makes a lot of errors.
    Thank you!

  • Lorenz

    1C) now I understand why people don't use header files and includes, what a mess for few lines of code!
    this part should really be automated in some way, I had to do it by looking at the results since I had too many compiler errors :'(

  • Dany

    1c) What if i want to do similar(for example) friend function but inside another class like this:




    Is there any way to implement this "mutual friendship" without having circular include?

    • As long as Vector3d.h doesn't need `Point3d`'s definition, you can use a forward declaration of `Point3d` in Vector3d.h and you're fine.
      If `Vector3d` also wants to friend a function in `Point3d`, I don't think you can do that (Because of circular dependencies). You could friend the entire class as opposed to friending a single function.

  • sklv

    Hi Alex,

    Unintentionally instead of declaring
    class Vector3d in Point3d.h file
    i also used include "Vector3d.h"
    and then use class Vector3d
    This caused m_x,m_y,m_z to be private for the Point3d class
    Why is that?

    • If Point3d.h includes Vector3d.h you end up with a circular include, because Vector3d.h includes Point3d.h. C++ doesn't support circular includes, so it shouldn't compile. This shouldn't cause an access error though. I assume you did something else different too. Without code and the exact error message, I can't tell what happened.


    why are we passing object to friend function as a reference?

    why "void reset(Accumulator &accumulator)" instead of "void reset(Accumulator accumulator)"

  • sekhar

    Hi Alex,

    Could you please elaborate on the details of below statement with example :

    "Be careful when using friend functions and classes, because it allows the friend function or class to violate encapsulation. If the details of the class change, the details of the friend will also be forced to change. Consequently, limit your use of friend functions and classes to a minimum."

    Just curious to know how friend functions can violate encapsulation ?

    Thanks in advance.

    • Alex

      Basically, encapsulation prevents the internal state of your class from being accessed or altered directly. Friend functions have direct access to the internal state of the class they're a friend of, and can read/alter it, which violates encapsulation. In the example in the lesson, the Display class is directly accessing Storage's private members m_nValue and m_dValue. This violates the encapsulation of the Storage class. If Storage were ever to change the name or type of its members, we'd probably have to update the Display class too, since it's directly accessing these members.

  • sekhar

    Since Display::displayItem(const Storage&) being friend function of Storage class, displayItem has access to private members of the Storage class. Suppose Storage class has access to the Data base and holds the handle and don't want displayItem being accessing this handle and access only few other private members of Storage class, How can it be prevented ? Sample code as below :

    Want Display::displayItem() to access m_data1 & m_data2 but not dbAccess() function. How can it be prevented ?

    • Declare @dbAccess private,
      @m_data1 and @m_data2 protected.

      • sekhar

        When friend function would be able to access private members of Storage class, how this can be prevented ? Could you please clarify.

        • Nevermind my previous comment, I thought @Display inherited from @Storage.
          friend function have access to all private members, you can't restrict them.

          • sekhar

            Thanks nascardriver. Alex, any thoughts to overcome above problem ?

            • sekhar

              Hi Alex, nascardriver,

              Only way could acheive for the above problem is as below:

              Don't know if this is the right design approach ? Any comments welcomed.

  • Sekhar

    Under the Friend class topic, in the Friend class example of Display and Storage, Is it better to make to take const reference in void displayItem(Storage &storage); as  void displayItem(const Storage &storage);  as there would be no scope for Display's member function to modify storage object's private data ?

  • Anthony

    'A better solution is to put each class definition in a separate header file, with the member function definitions in corresponding .cpp files. That way, all of the class definitions would have been visible immediately in the .cpp files, and no rearranging of classes or functions is necessary!'

    But there's still a hidden complexity as I see it. Most of the answer to 1c is pretty straightforward providing we simply #include where we should by convention. But there is still one extra little complexity, namely the forward declaration in Point3d.h:

    class Vector3d

    I can't get my head around this. Is there a simple explanation? Why won't #include "Vector3d.h" do? (It doesn't, I checked..)

    #including generally still seems like magic to me. Well, the secret to the ORDER of the #included headers seems opaque.

    Thanks :)

    • @Point3d.h doesn't use @Vector3d for anything other than a reference. All it needs to know is that @Point3d is a class type. Including the entire header would cause a circular include.
      @Point3d.h includes @Vector3d.h
      @Vector3d.h includes @Point3d.h
      @Point3d.h includes @Vector3d.h

  • Anthony

    So to summarize the case where you're doing it all in one file:

    You have two classes, class A and class B. Class B contains a function you want to be a friend function of class A. Here are the steps:
    1. In class A's definition, put a declaration for the friend function prepended by the word 'friend'.
    2. Move class B's definition above class A's definition so that it will be seen first by the compiler.
    3. Put a forward declaration for class A up above class B's definition.
    4. Move the friend function's definition out of class B's definition to down below class A's definition, and prepend with class B's name and the scope operator.

    Golly, this is a real pain!

    • Eberhart Petersen

      I agree, this whole topic seems way too complicated for the functionality and utility gained. That's why skipped quiz 1c.

  • Max

    Hey Alex/Nascar,

    If friend was removed from the reset function prototype, would using the scope resolution operator when defining the function outside of the class make reset a member function? I am having some trouble with the function being declared inside of the class, yet not being a member function.

    • Alex

      Friends and members are separate concepts. In neither case is reset() a member function. However, if reset() is a friend of the class, then reset() can directly access private members of the class. Otherwise it can't.

  • Arthur

    in the solution for this quiz 1c

    I am wondering if this is written this way because it has not been updated like the beginning of the tutorial and is showing copy initialization as a result ?

    should it read

    there is also

    should that read

    & should they actually be uniform initialized as 0.0 right at declaration? instead of having the defaults initialize them?

    not criticizing and realize this page was written 11 years ago just asking because this section is not updated and leaves me unsure...

  • Andu


        // Make the Display::displayItem member function a friend of the Storage class (requires seeing the full declaration of class Display, as above)
        friend void Display::displayItem(Storage& storage);

    // Now we can define Display::displayItem, which needs to have seen the full declaration of class Storage
    void Display::displayItem(Storage &storage)

    I guess it should be <<full definition>> in the above comments of last example.

    p.s. great work! :)
    p.s.2 How can I embed code snippets?

  • david

    1- int the solution for 1C above, "Point3d.h" is included in the "Vector3d.h".
    is that necessary? because I haven't done that and the program compiled fine.

    2- when I have to include files like "iostream" in a header file should I do that before the header guard or after it?

    • 1. Yes. Your code works, because you forgot include guards, have an include to Point3d.h in Vector3d.cpp and/or you are using an include order that makes it work.
      If file A uses something from file B, file A should include file B or have a forward declaration.

      2. The header guard comes first.

      • david

        Hi nascardriver
        This is my Vector3d

        as I said it compiles with not even a warning. any explanation?
        I am using codeBlocks with GCC on Ubuntu 18.04

        • > any explanation?
          As I said, you forgot include guards, have an include to Point3d.h in Vector3d.cpp and/or you are using an include order that makes it work.
          Without full code, I can't tell what exactly is causing it. Compare your code to Alex' and you might even find it yourself. Whatever it is, you should add the include.

  • Liam

    I'm trying to give a member function friend access to another class across multiple files, as in the last example, but not finding it as easy as advertised. Can anyone suggest what I'm doing wrong?





    • A.h Line 7: The compiler doesn't know what @B is. You need to add

      in A.h above line 4 to tell the compiler that there is a class called B, it's just not yet declared.

      • Liam

        Thank you for the quick response. Actually, there were many errors in the above code, but I finally got it to compile like this:





        Is there a simpler way of doing it? This solution doesn't seem easier than compiling in a single file, as the tutorial suggests.

        Part 2: What I'm actually trying to do is even complicated than this simple example, and I can't get it to work. In my project, class B has an instance of class A as a private variable, and B should have access to certain private member functions of A. But if I put an instance of A inside B, then B.h needs to have ' #include "A.h" ', and then it all gets screwed up. Is there a solution to this problem?

        The easiest thing is probably just to make class A a friend of B, but I'm wondering if there's a way of doing it through friend member functions for more complete encapsulation.

        • > Is there a simpler way of doing it?
          No. If you want to use something you need a declaration or definition. You can't have a definition, because it will lead to circular includes, so you need declarations.

          > easier than compiling in a single file
          You have the same problem in a single-file-solution

          > B.h needs to have ' #include "A.h" ' [...] Is there a solution to this problem?
          b.hpp can include a.hpp as long as a.hpp doesn't include b.hpp.
          If a.hpp has to include b.hpp, @B cannot store an object of type @A. @B can always store a pointer/reference to an @A.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]