C++回顾之友元

来源:互联网 发布:数据分析师认证 编辑:程序博客网 时间:2024/05/10 05:35

http://blog.csdn.net/ab198604/article/details/19204045

总的来说,友元分为两类:友元函数与友元类。友元是针对类而言,它提供了一种非类的成员函数来访问类的非公有成员的一种机制。可以把一个函数指定为某类的友元,这个函数称为这个类的友元函数。也可以将类A指定为类B的友元,则类A是类B的友元类,类A的所有成员函数均是类B的友元函数,均可以访问类B的非公有成员。

        友元函数的注意事项:

        (1)友元函数不是类的成员函数,在函数体中访问对象的成员,必须用“对象名.对象成员"方式来访问, 友元函数可以访问类中的所有成员(公有,私有,保护),而一般的函数只能访问类的公有成员。

        (2)友元函数不受类中的访问权限关键字的限制,可以将它放在类的公有,私有,保护部分,结果均一样。

        (3)某类的友元函数的作用域并非该类作用域,如果该友元函数是另一类的成员函数,则其作用域为另一类的作用域,否则与一般函数相同。

        (4)友元函数破坏了面向对象设计的封装特性。所以应该尽量少用。


        友元类

        如果某类B的成员函数会频繁地访问类A的数据成员,而类A的数据成员的private/protected限制造成了类B存取的麻烦,B只能通过A的Public的成员函数进行间接存取。这种情况下可以将类B作为类A的友元类,即类A向类B提供私有和保护成员的访问权限,让类B可以直接存取。

        友元类中的所有成员函数均可以看作是另一类的友元函数。

        友元类的声明: friend chass 类名;


        下面是友元函数的例子

        友元函数可以在类中声明,声明时在函数前增加friend关键字,然后在类体外定义,也可以直接在类中声明定义。这两种方式均可。下面例子中采取的是类中声明,类体外定义的方式。

        

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class Point  
  2. {  
  3.     friend double Distance(const Point &p1, const Point &p2); //类体中声明  
  4.   
  5. public:  
  6.     Point(int x, int y):x_(x), y_(y)  
  7.     {};  
  8.   
  9. private:  
  10.     int x_;  
  11.     int y_;  
  12. };  
  13.   
  14. //类体外定义友元函数  
  15. double Distance(const Point &p1, const Point &p2)  
  16. {  
  17.     double dx = p1.x_ - p2.x_;  //直接访问类的私有成员  
  18.     double dy = p1.y_ - p2.y_;  
  19.     return sqrt(dx*dx+dy*dy);  
  20. }  
  21.   
  22. int main()  
  23. {  
  24.     Point p1(3,4);  
  25.     Point P2(6,8);  
  26.     cout << Distance(p1,p2) << endl;  
  27.   
  28.     return 0;  
  29. }  

        下面是友元类的例子:

        

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. class Television  //电视类  
  2. {  
  3.     friend class TeleController;//友元类声明  
  4.       
  5. public:  
  6.     Television(int volume, int chanel): volume_(volume), chanel_(chanel){}  
  7.   
  8. private:  
  9.     int volume_; //音量  
  10.     int chanel_; //频道  
  11. };  
  12.   
  13. class TeleController //遥控器类  
  14. {  
  15. public//类中的每个成员函数都是电视类的友元函数,都可以访问电视类的私有数据成员  
  16.     void VolumeUp(Television &tv)  
  17.     {  
  18.         tv.volume_ += 1; //音量加1  
  19.     }  
  20.   
  21.     void VolumeDown(Television &tv)  
  22.     {  
  23.         tv.volume_ -= 1;  
  24.     }  
  25.   
  26.     void ChanelUp(Television &tv)  
  27.     {  
  28.         tv.chanel_ +=  1; //频道加1  
  29.     }  
  30.   
  31.     void ChanelDown(Television &tv)  
  32.     {  
  33.         tv.chanel_ -= 1; //频道减1  
  34.     }  
  35. };  
  36.   
  37.   
  38. int main()  
  39. {  
  40.     Television tv(1,1);  
  41.     TeleController tc;  
  42.     tc.ChanelUp(tv);  
  43.     return 0;  
  44. }  

        友元类需要注意以下几点:

        (1)友元关系是单向的; 

        (2) 友元关系不能被传递: A是B的友元,B是C的友元,则A是C的友元,这种传递不成立

        (3) 友元关系不能继承:   A是B的友元,A的派生类C也是B的友元,这是不成立的。


0 0