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


Leave a Reply

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

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