Friend Function in C++

Filed Under: C++
Friend Function in C++

Friend Functions in C++ are a category of functions that can access private and protected members of a class while being a public function/outside the class.

You may wonder; is this even possible? Well, modern C++ says yes!

Let us look at how we can use these functions in C++.


Friend Function in C++

We call a function a friend function if the function definition is prefixed with the friend keyword.

We cannot use the friend prefix outside a class, so it can only be used in the member function declaration.

For example, if we want to use the friend keyword in the declaration, we can use it like this:

#include <iostream>

using namespace std;

class MyClass {
    private:
        int a, b;
    public:
        MyClass(int a, int b) {
            // Constructor
            this->a = a;
            this->b = b;
        }
        void set_a(int val);
        void set_b(int val);
        int get_a() {
            return a;
        }
        int get_b() {
            return b;
        }
        // Declare a friend function of this class
        friend void my_fun(MyClass& my_obj, int val, char option);
};

void my_fun(MyClass& my_obj, int val, char option) {
    // Friend function that sets the private variables
    // based on the option
    if (option == 'a') {
        // Set a
        my_obj.a = val;
    }
    else {
        // Set b
        my_obj.b = val;
    }
}

int main() {
    MyClass my_obj(1, 2);
    cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;

    // Friend functions can be accessed from outside the class!
    my_fun(my_obj, 20, 'a');
    my_fun(my_obj, 40, 'b');
    cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
    return 0;
}

Here, my_fun() is a friend function of MyClass, so it can access the private members too!

Notice that we can access a friend function from outside the class as well.

The above friend function sets the value of the private members a or b directly!

Output

my_obj.a = 1 and my_obj.b = 2
my_obj.a = 20 and my_obj.b = 40

A friend function can either be within the same class or even inside another class. But it must be a member function.

Let’s look at these two cases one by one.

Friend Function within the same class in C++

The above example showed us that we can use a friend function inside the same class.

class MyClass {
    private:
        int a, b;
    public:
        MyClass(int a, int b) {
            // Constructor
            this->a = a;
            this->b = b;
        }
        void set_a(int val);
        void set_b(int val);
        int get_a() {
            return a;
        }
        int get_b() {
            return b;
        }
        // Declare a friend function of this class
        // within the same class itself!
        friend void my_fun(MyClass& my_obj, int val, char option);
};

We’ll move on to the next case; when a friend function is inside another class!

This is actually inside another topic, called Friend Classes, but they are directly related to each other.

Friend Classes in C++ – Friend Functions in another class

Any class B which has friend functions of another class A is called a Friend Class of A.

Similar to friend functions, any member function inside the friend class B can access private and protected members of A.

Let’s understand this more clearly using an example.

I will use the previous example, but I will add another class Student, and make it as the friend class of MyClass.

#include <iostream>
#include <string>

using namespace std;

class Student;

class MyClass {
    private:
        int a, b;
    public:
        MyClass(int a, int b) {
            // Constructor
            this->a = a;
            this->b = b;
        }
        void set_a(int val);
        void set_b(int val);
        int get_a() {
            return a;
        }
        int get_b() {
            return b;
        }
        // Declare a friend function of this class
        friend void my_fun(MyClass& my_obj, int val, char option);
        // Make Student a friend Class of MyClass
        friend Student;
};

Now, let’s write the Student class:

class Student {
    private:
        string name;   
        int marks;
    public:
        Student(string s_name, int s_marks) {
            // Constructor
            name = s_name;
            marks = s_marks;
        }
        int get_marks() {
            return marks;
        }
        string get_name() {
            return name;
        }
        void set_marks(Student& stud, int s_marks) {
            stud.marks = s_marks;
        }
        void set_name(Student& stud, string s_name) {
            stud.name = s_name;
        }
        void change_a(MyClass& my_obj, int val) {
            // You need to pass the object by reference.
            // Otherwise, it will not reflect the changes on
            // the original object
            my_obj.a = val;
        }
        void change_b(MyClass& my_obj, int val) {
            // You need to pass the object by reference.
            // Otherwise, it will not reflect the changes on
            // the original object
            my_obj.b = val;
        }
};

As you can see, I am using change_a() and change_b() to change the MyClass object attributes directly!

Let’s now run the complete snippet below.

#include <iostream>
#include <string>

using namespace std;

class Student;

class MyClass {
    private:
        int a, b;
    public:
        MyClass(int a, int b) {
            // Constructor
            this->a = a;
            this->b = b;
        }
        void set_a(int val);
        void set_b(int val);
        int get_a() {
            return a;
        }
        int get_b() {
            return b;
        }
        // Declare a friend function of this class
        friend void my_fun(MyClass& my_obj, int val, char option);
        // Make Student a friend Class of MyClass
        friend Student;
};

class Student {
    private:
        string name;   
        int marks;
    public:
        Student(string s_name, int s_marks) {
            // Constructor
            name = s_name;
            marks = s_marks;
        }
        int get_marks() {
            return marks;
        }
        string get_name() {
            return name;
        }
        void set_marks(Student& stud, int s_marks) {
            stud.marks = s_marks;
        }
        void set_name(Student& stud, string s_name) {
            stud.name = s_name;
        }
        void change_a(MyClass& my_obj, int val) {
            // You need to pass the object by reference.
            // Otherwise, it will not reflect the changes on
            // the original object
            my_obj.a = val;
        }
        void change_b(MyClass& my_obj, int val) {
            // You need to pass the object by reference.
            // Otherwise, it will not reflect the changes on
            // the original object
            my_obj.b = val;
        }
};

void my_fun(MyClass& my_obj, int val, char option) {
    // Friend function that sets the private variables
    // based on the option
    if (option == 'a') {
        // Set a
        my_obj.a = val;
    }
    else {
        // Set b
        my_obj.b = val;
    }
}

int main() {
    MyClass my_obj(1, 2);
    cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;

    // Friend functions can be accessed from outside the class!
    my_fun(my_obj, 20, 'a');
    my_fun(my_obj, 40, 'b');
    cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;

    // Class Student objects
    Student stud("Amit", 34);
    cout << "stud.name = " << stud.get_name() << " and stud.marks = " << stud.get_marks() << endl;

    // Change my_obj.a and my_obj.b using the friend class
    stud.change_a(my_obj, 100);
    stud.change_b(my_obj, 200);
    
    cout << "After using the Friend Class methods,\n";
    cout << "my_obj.a = " << my_obj.get_a() << " and my_obj.b = " << my_obj.get_b() << endl;
    return 0;
}

Output

my_obj.a = 1 and my_obj.b = 2
my_obj.a = 20 and my_obj.b = 40
stud.name = Amit and stud.marks = 34
After using the Friend Class methods,
my_obj.a = 100 and my_obj.b = 200

Indeed, the changes made by the friend class methods are indeed reflected in my_obj.


Conclusion

Hopefully, that gives you a good idea of what friend functions in C++ are.

C++ has given us this flexibility to even modify private and protected variables using friend methods. Make sure you use them wisely!

References


close
Generic selectors
Exact matches only
Search in title
Search in content