什么是友元?
在类中,一般数据成员为类的私有成员,而类的私有成员只能被类的成员函数所访问,例如类A中有一个成员变量x,那么类B中的成员函数不能访问类A中的x。全局函数也是没办法直接访问类A中的x。而友元给我们提供了一个种方法,可以用不属于A的成员函数来直接访问类A中的x。
友元可以是(1)全局函数,(2)类的成员函数,(3)整个类
注意:虽然友元函数可以访问类内部的私有成员,但是友元函数并不是这个类的成员函数。还有因为友元需要访问类中的成员,所以友元中都会有一个该类的参数,有可能是值也有可能是指针,如果没有参数,那么就在友元函数内部自己建立一个类的对象。因为友元不属于这个类,所以友元声明在这个类的private,public,protected都可以,没有影响。友元关系是单向的 友元关系不能被传递 友元关系不能被继承
友元的用法:友元函数时定义在类的作用域之外,但是要在类内进行声明。声明时需要加关键字friend.
(1)全局函数声明形式:friend 返回值类型 函数名(参数列表);
1 #include<iostream> 2 using std::endl; 3 using std::cout; 4 5 class Test{ 6 int m_i; 7 public: 8 Test(int ii = 0) :m_i(ii){ cout << "consturctor" << endl; } 9 ~Test(){ cout << "destructor" << endl; } 10 friend void display(const Test& vt);//把全局函数display声明为class Test的友元函数 11 int getI()const{ return m_i; } 12 void setI(int ii){ m_i = ii; } 13 }; 14 15 void display(const Test& vt){ 16 cout << vt.m_i << endl;//display 访问类Test的私有成员变量 17 } 18 19 int main(){ 20 Test vt; 21 display(vt); 22 return 0; 23 24 }
(2)类的成员函数声明形式:friend 返回值类型 类名::函数名(参数类型)
注意:若把A的类的函数声明为B的类的友元,那么必须把A声明在B的前面。
1 #include<iostream> 2 using std::endl; 3 using std::cout; 4 class Test;//不完全的类型说明,是为了void display(const Test& vt);用的 5 class A{//类A的声明放在了Test的前面 6 public: 7 void display(const Test& vt); 8 9 }; 10 class Test{ 11 friend void A::display(const Test& vr);//声明A的成员函数display为Test的友元函数 12 private: 13 int m_i; 14 public: 15 16 Test(int ii = 0) :m_i(ii){ cout << "consturctor" << endl; } 17 ~Test(){ cout << "destructor" << endl; } 18 int getI()const{ return m_i; } 19 void setI(int ii){ m_i = ii; } 20 21 }; 22 23 24 void A::display(const Test& vr){ 25 cout << vr.m_i << endl; 26 } 27 28 29 30 31 int main(){ 32 Test vt; 33 A a; 34 a.display(vt); 35 return 0; 36 37 }
(3)整个类声明为友元的形式:friend class 类名;
1 #include<iostream> 2 using std::endl; 3 using std::cout; 4 5 6 class Test{ 7 friend class A;//把类A声明为Test的友元类 8 private: 9 int m_i; 10 public: 11 12 Test(int ii = 0) :m_i(ii){ cout << "consturctor" << endl; } 13 ~Test(){ cout << "destructor" << endl; } 14 int getI()const{ return m_i; } 15 void setI(int ii){ m_i = ii; } 16 17 }; 18 class A{ 19 public: 20 void display(const Test& vt); 21 22 }; 23 24 void A::display(const Test& vr){ 25 cout << vr.m_i << endl; 26 } 27 28 29 30 31 int main(){ 32 Test vt; 33 A a; 34 a.display(vt); 35 return 0; 36 37 }