9.4.4 友元类

    类A作为类B的友元时,类A称为友元类。A中的所有成员函数都是B的友元函数,都可以访问B中的隐藏信息。

    A可以在B的public部分或private部分进行声明,方法如下。


    friend<类名>;//友元类类名

    见代码9.6。

    代码9.6 友元类FriendClass


    <—————————————-文件名:point.h—————————————————> 01 #include<iostream> 02 #include<cmath> 03 using namespace std; 04 class cz;//声明类cz 05 class point//定义point类 06 { 07 private: 08 int x,y; 09 friend cz;//友元类的声明,位置同样不受限制 10 public: 11 point(int i=0,int j=0)//构造函数,带默认参数值 12 { 13 x=i; 14 y=j; 15 } 16 void disp()//成员函数,输出点的信息 17 { 18 cout<<"("<<x<<","<<y<<")"; 19 } 20 }; 21 class cz//类cz的定义,其中所有的函数都是point类的友元函数 22 { 23 public: 24 float dis(point&p1,point&p2)//可访问p1和p2的private成员 25 { 26 float d; 27 d=sqrt((p1. x-p2.x)(p1.x-p2.x)+(p1.y-p2.y)(p1.y-p2.y)); 28 return d; 29 } 30 void Set(point*p1,int a,int b)//可访问p1和p2的private成员 31 { 32 p1->x=a; 33 p1->y=b; 34 } 35 }; <————————————文件名:example906.cpp———————————————> 36 #include"point.h" 37 int main() 38 { 39 cz cz1;//声明一个cz类的对象cz1 40 point p1(1,2),p2(4,5);//声明两个point类对象p1和p2 41 p1. disp();//输出点p1的信息 42 cout<<"与"; 43 p2. disp();//输出点p2的信息 44 cout<<"距离="<<cz1.dis(p1,p2)<<endl;//调用cz1的成员函数dis计算两点间距 45 46 cz1. Set(&p1,3,4);//调用cz1的成员函数Set改写p1中的private成员x和y 47 p1. disp();//修改后的点p1信息输出 48 cout<<endl;//换行 49 return 0; 50 }

    输出结果如下所示。


    (1,2)与(4,5)距离=4.24264 (3,4)

    【代码解析】在代码第9行,类cz被声明为类point的友元类,则cz中的所有成员函数都称为point的友元函数,对比代码9.6和代码9.5可知,当把cz类声明为point类的友元类时,并不要求先定义cz,只要先对其进行声明即可,关于友元类有以下几个问题需要注意。

    ❑友元关系是单向的,不具有交换性。若类X是类Y的友元,类Y不一定是类X的友元,要看在类中是否有相应的声明。

    ❑友元关系不具有传递性。若类X是类Y的友元,类Y是Z的友元,类X不一定是类Z的友元,同样要看在类中是否有相应的声明。

    ❑友元关系不能被继承,关于继承的相关介绍请参考第10章。