Introduce friend function and friend class in C++ programming

  • 2020-05-05 11:36:53
  • OfStack

A class can have members of public, protected, private, public, public, public, public, public, public, public, public Now, let's add an exception -- friends (friend).

fnend means "friend" or "close friend". Some families may do so: the living room is open to all visitors, and the bedroom in addition to the members of the family can enter, but also allow good friends to enter. In C++, this relationship is declared as the key friend, which is often translated into Chinese as a friend. Friends can access private members of classes with which they are friends, including friend functions and friend classes. If you are not used to the term friend, you can use friend to mean friend.
friend function

Functions that are defined outside of the current class and are not part of the current class can also be declared in the class, but they are preceded by the friend keyword to form friend functions. A friend function can be a nonmember function that does not belong to any class, or a member function of another class.

The friend function can access all members of the current class, including the private attribute.

1) declare ordinary functions as friend functions.


#include<iostream>
using namespace std;
class Student{
private:
 char *name;
 int age;
 float score;
public:
 Student(char*, int, float);
 friend void display(Student &); // will display Declare as a friend function 
};
Student::Student(char *name, int age, float score){
 this->name = name;
 this->age= age;
 this->score = score;
}
// Ordinary member function 
void display(Student &stu){
 cout<<stu.name<<" The age is  "<<stu.age<<" , the result is  "<<stu.score<<endl;
}
int main(){
 Student stu(" Xiao Ming ", 16, 95.5f);
 display(stu);
 return 0;
}

Result:


 Xiao Ming's age is  16 , the result is  95.5

Note that display is a function that is defined outside of the class and not qualified with Student. It is a non-member function that does not belong to any class and outputs information about students. If the display function is not declared as friend in the Student class, it cannot reference the private members name, age, score in Student. You can test it yourself, delete line 11 from the above program, and observe the information at compile time.

Now that display is declared to be an friend function of the Student class, display can use the private members name, age, score in Student. However, note that when using these member variables, you must add the object name, not:


cout<<name<<" The age is  "<<age<<" , the result is  "<<score<<endl;


Because display is not a member function of the Student class, members of the Student class cannot be used by default and must specify which objects to access.

2) declare member functions of other classes as friend functions
The friend function can be not only a normal function (a non-member function), but also a member function in another class. See the following example:


#include<iostream>
using namespace std;
class Address; // right Address An early reference declaration for a class  
// The statement Student class 
class Student{
private:
 char *name;
 int age;
 float score;
public:
 Student(char*, int, float);
 void display(Address &);
};
// The statement Address class 
class Address{
private:
 char *province;
 char *city;
 char *district;
public:
 Address(char*, char*, char*);
 // will Student Member functions in a class display Declare as a friend function 
 friend void Student::display(Address &);
};
Address::Address(char *province, char *city, char *district){
 this->province = province;
 this->city = city;
 this->district = district;
}
// The statement Student Class into constructors and member functions 
Student::Student(char *name, int age, float score){
 this->name = name;
 this->age= age;
 this->score = score;
}
void Student::display(Address &add){
 cout<<name<<" The age is  "<<age<<" , the result is  "<<score<<endl;
 cout<<" Home address: "<<add.province<<" province "<<add.city<<" The city "<<add.district<<" area "<<endl;
}
int main(){
 Student stu(" Xiao Ming ", 16, 95.5f);
 Address add(" shaanxi ", " Xi 'an ", " Wild goose pagoda ");
 stu.display(add);
 return 0;
}

Result:


 Xiao Ming's age is  16 , the result is  95.5
 Home address: yanta district, xi 'an city, shaanxi province 

In this example, two classes Student and Address are defined. Line 26 of the program declares the member function display in the Student class as a friend function, from which display can access the private member variable of the Address class.

Two notes:
The Address class is predeclared in line 4 of the program because it was used in Student class before the Address class was defined. If it is not predeclared, the compilation will report an error, indicating "Address" has not been declared. Predeclaration of a class is the same as predeclaration of a function.

The Student class declaration and definition are separated, and Address is placed in the middle, because the Student::display() function body USES the Address class members, which must appear after the Address class body (which specifies which members).

Here is a brief introduction to class advance declarations. In general, classes must be formally declared before they can be used; However, in some cases (as shown in the example above), you can also use it first, as long as you make an advance declaration.

It should be noted, however, that the scope for early declaration of a class is limited. Only after a class has been formally declared can it be used to create objects. If you add a line after line 4 above:


Address obj; // An attempt was made to define an object 


Errors occur at compile time. Because an object is created to allocate memory space for the object, the compilation system cannot determine how much space should be allocated for the object until the class is formally declared. The compiler can't determine how much space to leave for an object until it has "seen" the body of the class (actually, the member variables). After a class has been prereferenced, you can use the class name to define a pointer variable to an object of that type or a reference variable to an object of that type (as in this case, the reference variable to an Address class object). This is because the size of the pointer and reference variables themselves is fixed, independent of the size of the class object to which they point.

Note that the program formally declares the Address class before defining the Student::display() function. This is because the member variables province, city, district of Address class are used in the Student::display() function body, and the compiler cannot recognize these member variables without formally declaring the Address class.

A function can be declared as a "friend" by more than one class, so that private members in more than one class can be referenced.
friend class

Not only can a function be declared a "friend" of a class, but an entire class (such as the B class) can be declared a "friend" of another class (such as the A class). The B class is then a friend of the A class.

All functions in the friend class B are friend functions of the A class, and all members of the A class can be accessed. In the body of the A class, declare the B class as its friend with the following statement:


friend B;


The general form of declaring a friend class is


friend  The name of the class ;

Two things need to be said about friends:
Friend relationships are one-way rather than two-way. If it is declared that the B class is a friend of the A class, it does not mean that the A class is a friend of the B class.
If the B class is a friend of A class and C class is a friend of B class, it is not the same as if C class is a friend of A class.

In practice, it is safer not to declare an entire class as a friend unless it is absolutely necessary, but to declare only the member functions that are actually needed as friends.


Related articles: