Friend Function in C++

Private and protected class members are not allowed be accessed from outside the class. We can access the private members only from the same class, whereas, the protected members can be accessed from the same class and from its derived classes. But a friend function can access the private and protected members of the granting class.

class Circle {
private:
    float radius_;

public:
    Circle(float r = 0) {
        radius_ = r;
    }

    float area() {
        return (3.14 * radius_ * radius_);
    }
};

In this example Circle class, we have a private data, radius_. We made radius_ private because we don’t want anyone to access and modify it outside the class.

Now, say we want to have a non-member function that will merge two circles. Merging two circles means that creating a bigger circle from two smaller ones. The merged circle’s radius will be the summation of the two smaller ones.

The new function will need to access the radius of the input circle objects which are private. It can not do that. But still we can grant this function access to the private data member by making it a friend of the class. It means that the class is trusting this non-member function that it will not make any harm to the private data members.

The concept is like carefully broadening data access scope beyond the member functions instead exposing that to anyone and everyone. That way, it preserved the spirit of encapsulation.

class Circle {
private:
    float radius_;

public:
    Circle(float r = 0) {
        radius_ = r;
    }

    float area() {
        return (3.14 * radius_ * radius_);
    }

    friend Circle mergeCircles(Circle &a, Circle &b);
};

We made the new mergeCircles() function a friend of the class Circle by putting a ‘friend‘ keyword at the beginning.

Now this function can be defined anywhere.

Circle mergeCircles(Circle &a, Circle &b) {
    Circle result;

    float merged_radius = a.radius_ + b.radius_;

    result.radius_ = merged_radius;

    return result;
}

Here we accessed the private member radius_ of a and b objects. Also changed the radius of the result object.

Program with Friend Functions

#include <iostream>
using namespace std;

class Circle {
private:
    float radius_;

public:
    Circle(float r = 0) {
        radius_ = r;
    }

    float area() {
        return (3.14 * radius_ * radius_);
    }

    friend Circle mergeCircles(Circle &a, Circle &b);
};

Circle mergeCircles(Circle &a, Circle &b) {
    Circle result;

    float merged_radius = a.radius_ + b.radius_;

    result.radius_ = merged_radius;

    return result;
}

int main() {
    
    Circle a(10);
    Circle b(20);

    Circle m = mergeCircles(a, b);

    cout << "Area of the merged cirle: " << m.area() << endl;

    return 0;
}
$ g++ -o test test.cpp 
$ ./test 
Area of the merged cirle: 2826

Friend Member Function

In the above example, the mergeCircles() function is a global one. But it could have been a member function of another class.

We modified the code to make the mergeCircles() a member function of another call.

#include <iostream>
using namespace std;

class Circle; // Forward declaration.

class AnotherClass {
public:
    Circle mergeCircles(Circle &a, Circle &b);
};

class Circle {
private:
    float radius_;

public:
    Circle(float r = 0) {
        radius_ = r;
    }

    float area() {
        return (3.14 * radius_ * radius_);
    }

    friend Circle AnotherClass::mergeCircles(Circle &a, Circle &b);
};

Circle AnotherClass::mergeCircles(Circle &a, Circle &b) {
    Circle result;

    float merged_radius = a.radius_ + b.radius_;

    result.radius_ = merged_radius;

    return result;
}

int main() {
    
    Circle a(10);
    Circle b(20);
    AnotherClass r;

    Circle m = r.mergeCircles(a, b);

    cout << "Area of the merged cirle: " << m.area() << endl;

    return 0;
}

Important differences to notice.

In time declaring the friend function, the class name is also mentioned along with the function name.

friend Circle AnotherClass::mergeCircles(Circle &a, Circle &b);

In main(), we can not call this function directly. That’s why we created an object, r, from AnotherClass and then called the function in the context of that object.

Circle m = r.mergeCircles(a, b);

Note: Only the mergeCircle() member function of AnotherClass can access the private members of Circle class. No other member functions of AnotherClass will be able to do that. But we can also grant access of Circle‘s private members to all member functions of AnotherClass by making the AnotherCall a friend class of Circle.

Friend Function Characteristics

  1. Friend function is not a member function of a class. So, it can not be called in the context of an object. We can not call it with a class name also like a static member functions. This functions are called like any other functions without a class or object.
  2. Friend functions can not access the class members directly. It needs an object to to do that.
  3. It can be declared either in the private or public part of the class.

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

Leave a Reply

Your email address will not be published. Required fields are marked *

0
0
0
0
0
0