Usage Summary of friend class in C + +

For a class that does not define public access rights, it is often useful to allow other classes to operate its private members. For example, you wrote a code for a binary tree. Node is a node class. It must be very convenient if the function connecting multiple nodes can access the private members of node without calling the public method.

Friend Classes

The friend keyword in C + + actually does this: indicate that other classes (or) functions in a class can directly access the private and protected members in the class.
You can indicate this:

friend class aClass;

Note: the declaration of friend in the class can be in a control domain of public, protected and private without affecting its effect. For example, if you have such a declaration in the protected field, the aClass class can also access the private members of the class.
Here is an example:

class Node   
{  
    private:   
       int data;  
       int key;  
       // ...  
  
    friend class BinaryTree; // class BinaryTree can now access data directly  
};  

In this way, BinaryTree can directly access the private members in the Node, as follows:

class BinaryTree  
{  
    private:  
       Node *root;  
  
    int find(int key);  
};  
int BinaryTree::find(int key)  
{  
    // check root for NULL...  
    if(root->key == key)  
    {  
        // no need to go through an accessor function  
        return root->data;  
    }  
    // perform rest of find  
}  

Friend Functions

The function of friend function is the same as that of friend class. It allows a function to access private and protected member variables in the class without its public interface.
You can state this:

friend return_type class_name::function(args);

Here is an example:

class Node 
{
    private: 
       int data;
       int key;
       // ...

    friend int BinaryTree::find(); // Only BinaryTree's find function has access
};

In this way, the find method can directly access the private member variables in the Node, while other methods in BinaryTree cannot directly access the member variables of the Node. (this is the difference between friend classes and friend functions)

The friend mechanism in C + + allows non-public members of a class to be accessed by a class or function. Friends are divided into three types: ordinary non class member functions as friends, class member functions as friends, and classes as friends.

1. Contents of friends

Friends include the declaration of friends and the definition of friends. The friend declaration defaults to extern, which means that the scope of the friend class or friend function has been extended to the scope containing the class definition, so it doesn't matter even if we define the friend function inside the class.

2 ordinary nonmember function friend

Such friend functions are usually operators, such as input and output operators. Examples are as follows:

//OpeClass.h  
#pragma once  
class OpeClass  
{  
    friend int func(const OpeClass xx);  
public:  
    OpeClass(void);  
    OpeClass(int x,int y);  
    ~OpeClass(void);  
private:  
    int width;  
    int height;  
};  
//OpeClass.cpp  
#include "OpeClass.h"  
  
  
OpeClass::OpeClass(void)  
{  
    width = 50;  
    height = 50;  
}  
  
  
OpeClass::OpeClass(int x,int y):width(x),height(y)  
{  
}  
  
  
OpeClass::~OpeClass(void)  
{  
}  
  
  
int func(const OpeClass xx)  
{  
    return xx.height * xx.width;  
}  
//main.cpp  
#include "OpeClass.h"  
#include <iostream>  
using namespace std;  
  
  
void main()  
{  
    OpeClass XO;  
    cout<<func(XO);  
    system("pause");  
}  

Class 3 as friends

Class as a friend, you should pay attention to the interdependence between the friend class and the original class. If the function defined in the friend class uses the private variables of the original class, you need to include the header file of the original class definition in the file of the friend class definition.
However, in the definition of the original class (the class containing the friend class declaration), it is not necessary to include the header file of the friend class, nor to declare the friend class before the class definition, because the friend class declaration itself is a declaration (it indicates that the friend class can be found outside the class). The example program is as follows:

//A.h  
#pragma once  
#include <iostream>  
using namespace std;  
class A  
{  
    friend class B;  
public:  
    ~A(void);  
    static void func()  
    {  
        cout<<"This is in A"<<endl;  
    }  
private:  
    A(){};  
    static const A Test;  
};  
//A.cpp  
#include "A.h"  
const A A::Test = A();  
A::~A(void)  
{  
}  
//B.h  
#pragma once  
#include "C.h"  
class B  
{  
public:  
    B(void);  
    ~B(void);  
    void func(C& c);  
};  
//B.cpp  
#include "B.h"  
#include "A.h"  
#include "C.h"  
#include <iostream>  
using namespace std;  
  
  
B::B(void)  
{  
}  
  
  
  
  
B::~B(void)  
{  
}  
  
  
void B::func(C& c)  
{  
    cout<<"This is in B"<<endl;  
    A::Test.func();  
    c.func(A::Test);  
}  
//C.h  
#pragma once  
class A;  
class C  
{  
public:  
    C(void);  
    ~C(void);  
    void func(const A& a);  
};  
//C.cpp  
#include "C.h"  
#include <iostream>  
using namespace std;  
  
C::C(void)  
{  
}  
  
C::~C(void)  
{  
}  
  
void C::func(const A& a)  
{  
    cout<<"This is in C"<<endl;  
}  
//main.cpp  
#include "A.h"  
#include "B.h"  
#include "C.h"  
#include <iostream>  
using namespace std;  
  
void main()  
{  
    B b;  
    C c;  
    b.func(c);  
    system("pause");  
}  

Class 4 member functions as friend functions

This is a little complicated, because you want the class member function as a friend, and you need to use the class qualifier when declaring a friend, so you must first define the class containing the friend function, but when defining the friend function, you must define the original class in advance. The usual practice is to define the class containing friend functions first, and then define the original class. This order cannot be disordered. (if it is a friend class, there is no such requirement), as shown below:

//B.h  
#pragma once  
class A;  
class B  
{  
public:  
    B(void);  
    ~B(void);  
    int func(A xx);  
};  
//A.h  
#pragma once  
#include "B.h"  
class A  
{  
friend int B::func(A xx);  
public:  
    A(void):mx(20),my(30){}  
    ~A(void){}  
private:  
    int mx;  
    int my;  
};  
//B.cpp  
#include "B.h"  
#include "A.h"  
  
  
B::B(void)  
{  
}  
  
  
B::~B(void)  
{  
}  
  
int B::func(A xx)  
{  
    return xx.mx * xx.my;  
}  
//main.cpp  
#include "A.h"  
#include "B.h"  
#include <iostream>  
using namespace std;  
void main()  
{  
    A a;  
    B b;  
    cout<<b.func(a)<<endl;  
    system("pause");  
}  

5 friends do not have reciprocity

If class B is a friend of class A, class A is not necessarily a friend of class B. It depends on whether there is a corresponding declaration in the class.

6 friends cannot be inherited

B is a friend class of a and C is a subclass of B. It can't be deduced that C is a friend of A

7 friends are not transitive

B is a friend of a and C is a friend of B. we can't deduce that C is a friend of A

8 classes that are friends with each other

In fact, there is nothing to pay attention to. The following is an example. Class A and class B are friends of each other

//A.h  
#pragma once  
class A  
{  
friend class B;  
public:  
    A(void);  
    ~A(void);  
    int funa(B& b);  
private:  
    int mx;  
    int my;  
};  
//A.cpp  
#include "A.h"  
#include "B.h"  
  
  
A::A(void)  
{  
    mx = 10;  
    my = 10;  
}  
  
  
A::~A(void)  
{  
}  
  
  
int A::funa(B& b)  
{  
    return b.mb * b.mc;  
}  
//B.h  
#pragma once  
class B  
{  
    friend class A;  
public:  
    B(void);  
    ~B(void);  
    int funb(A& a);  
private:  
    int mb;  
    int mc;  
};  
//B.cpp  
#include "B.h"  
#include "A.h"  
  
  
B::B(void)  
{  
    mb = 20;  
    mc = 20;  
}  
  
B::~B(void)  
{  
}  
  
int B::funb(A& a)  
{  
    return a.mx *a.my;  
}  
//main.cpp  
#include "A.h"  
#include "B.h"  
#include <iostream>  
using namespace std;  
void main()  
{  
    A a;  
    B b;  
    cout<<a.funa(b)<<endl;  
    cout<<b.funb(a)<<endl;  
    system("pause");  
}  

9 If you want to specify that both classes have member functions as each other's friends, the second class must be the friend of the first class

//A.h  
#pragma once  
  
// class B is a friend class of A  
class A  
{  
    friend class B;  
public:  
    A(void):ma(10),mb(20){}  
    ~A(void){}  
    int funa(B& b);  
private:  
    int ma;  
    int mb;  
};  
//B.h  
#pragma once  
#include "A.h"  
  
  
// A's function funa is a friend function of B  
class B  
{  
    friend int A::funa(B& b);  
public:  
    B(void);  
    ~B(void);  
    int funb(A& a);  
    int func(A& a);  
private:  
    int mx;  
    int my;  
};  
//A.cpp  
#include "A.h"  
#include "B.h"  
  
  
int A::funa(B& b)  
{  
    return  b.mx * b.my;  
}  
//B.cpp  
#include "B.h"  
  
B::B(void):mx(12),my(15)  
{  
}  
  
  
B::~B(void)  
{  
}  
  
  
int B::funb(A& a)  
{  
    return a.ma + a.mb;  
}  
  
int B::func(A& a)  
{  
    return a.ma * a.mb;  
}  
//main.cpp  
#include "A.h"  
#include "B.h"  
#include <iostream>  
using namespace std;  
void main()  
{  
    A a;  
    B b;  
    cout<<a.funa(b)<<endl;  
    cout<<b.funb(a)<<endl;  
    cout<<b.func(a)<<endl;  
}  

Reprinted from https://blog.csdn.net/ddupd/article/details/38053159

Tags: C++

Posted on Sat, 20 Nov 2021 19:32:55 -0500 by Johntron