Friend Function In C++

I’m having a problem with the friend function in C++. I understand that if a function is specified as a class’s buddy function, it may access any member variable or function, whether it is private, protected, or public.

The following programmes demonstrate how one function may be designated as a buddy function or a global function.

#include <iostream>
#include <map>
#include <set>
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
#include <numeric>
#include <string>
using namespace std;

class ABCD
{
public: 
    int a;
    int b;
    friend void friend_fun(const ABCD &obj);
};

void fun(const ABCD &obj)
{
    std::cout<<obj.a<<endl;
    std::cout<<obj.b<<endl;
};

void friend_fun(const ABCD &obj)
{
    std::cout<<obj.a<<endl;
    std::cout<<obj.b<<endl;
};


int main () 
{
     ABCD obj;
     obj.a = 20;
     obj.b = 30;
     fun(obj);
     friend_fun(obj);

    return 0;
}

However, while using doxygen to generate document references, I discovered another advantage of the friend function: its relationship with the class may be plainly explained because the friend function is mentioned after the member function in the HTML page. Nevertheless, if the function is not described as a friend in this manual, it will be treated as a global function, and it will not be listed with the class description in doxygen. So I intend to make all global functions that are related to a single class its buddy functions. I’m not sure if this is a good practise.

Functions should only be declared as friend if they have a legitimate need to bypass class access specifiers, because it allows another mechanism by which a class instance state can be changed without using the public functions.

They’re generally not wanted because it is harder to reason about the means which a class instance state can change.

Example: If the only possible ways that two unrelated classes can modify each others state is via public member functions, then you can debug any state issues by placing breakpoints or adding logging to those public member functions. Once you have friend functions, that no longer works because the state can be modified from anywhere.

The Google C++ style guide has an example of such a scenario where it is necessary, when using unit tests to inspect the private state of a class:

In some cases this is better than making a member public when you want to give only one other class access to it. However, most classes should interact with other classes solely through their public members.

Bear in mind that it is not only global functions that can be declared as friend, member functions of other classes, static or not, can be as well. Modifying your example:

class ABCD;

class Other {
public:
    void other_friend_fun(const ABCD &obj);
};

class ABCD
{
private:
    int a;
    friend void Other::other_friend_fun(const ABCD &obj);
};

void Other::other_friend_fun(const ABCD &obj) {
    std::cout << obj.a << std::endl;
}

int main() {
    ABCD obj;

    Other other;
    other.other_friend_fun(obj);

    return 0;
}

But saying all that, if Doxygen is making the relationship clearer, then by all-means use it - that’s what documentation is for, right? :slight_smile:

To add to this; always limit your friend scope as much as possible. Also, if class members are declared as public there is no need for friends.

Friends are essentially only required IF:

  • The problem is outside the realm of the class responsibility
  • The problem cannot be solved by getters, setters or internal state modification via public methods

Usually, if you have a friend function this is a code smell and is indicating your class design is sub-par and should be reworked in some form. This does not mean friends are completely useless, but they are something you resort to when dealing with limitations of your class hierarchy and this usually only happens on code base that has been around for a while.

1 Like