友元函数和友元类

友元函数和友元类


        采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元函数
      友元函数是可以直接访问类的私有成员的非成员函数。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend,其格式如下:
      friend  类型 函数名(形式参数);

      友元函数的声明可以放在类的私有部分,也可以放在公有部分,它们是没有区别的,都说明是该类的一个友元函数。
      一个函数可以是多个类的友元函数,只需要在各个类中分别声明。
      友元函数的调用与一般函数的调用方式和原理一致。

友元类
      友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。       
      当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下:
      friend class 类名;
      其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。

      例如,以下语句说明类B是类A的友元类:
      class A
      {
             …
      public:
             friend class B;
             …
      };
      经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。

      使用友元类时注意:
            (1)
友元关系不能被继承。
            (2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
            (3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

代码举例:以下代码VC6.0下编译通过。

一、使用友元函数调用类成员

 

  1. #include <iostream.h>   
  2. #include <string.h>   
  3.   
  4. class girl{  
  5. private:  
  6.     char *name;  
  7.     int age;  
  8.   
  9. public:  
  10.     girl(char *n,int d)  
  11.     {   
  12.         name=new char[strlen(n)+1];  
  13.         strcpy(name,n);  
  14.         age=d;  
  15.     }  
  16.   
  17.     friend void disp(girl &);   //声明为友元函数    
  18.   
  19.     ~girl(){delete name;}  
  20. };   
  21.   
  22. void disp(girl &x)              //定义友元函数   
  23. {   
  24.     cout<<"girl/'s name is:"<<x.name<<",age:"<<x.age<<endl;  
  25. }   
  26.   
  27. void main()  
  28. {   
  29.     girl e("jsfn_dai",24);  
  30.     disp(e);                    //调用友元函数   
  31. }  

 

二、一个友元函数访问两个不同的类

 

  1. #include <iostream.h>   
  2. #include <string.h>   
  3.   
  4. class boy;   
  5. class girl{  
  6.     char name[25];  
  7.     int age;  
  8. public:  
  9.     void init(char N[],int A);  
  10.     //声明函数为girl类的友元函数   
  11.     friend void prdata(const girl plg,const boy plb);   
  12. };           
  13.   
  14. void girl::init(char N[],int A)  
  15. {   
  16.     strcpy(name,N);  
  17.     age=A;  
  18. }  
  19.   
  20. class boy{  
  21.     char name[25];  
  22.     int age;  
  23. public:  
  24.     void init(char N[],int A);  
  25.     //声明函数为boy类的友元函数   
  26.     friend void prdata(const girl plg,const boy plb);   
  27. };  
  28.   
  29. void boy::init(char N[],int A)  
  30. {   
  31.     strcpy(name,N);  
  32.     age=A;  
  33. }  
  34.   
  35. void prdata(const girl plg,const boy plb)  
  36. {   
  37.  cout<<"女孩"<<plg.name<<','<<plg.age<<"岁;"<<endl;  
  38.  cout<<"男孩"<<plb.name<<','<<plb.age<<"岁。"<<endl;  
  39. }  
  40.   
  41. void main()  
  42. {   
  43.     girl G1,G2,G3;  
  44.     boy B1,B2,B3;  
  45.     G1.init("Stacy",12);  
  46.     G2.init("Judith",13);  
  47.     G3.init("Leah",12);  
  48.     B1.init("Jim",11);  
  49.     B2.init("Micheal",13);  
  50.     B3.init("Larry",12);  
  51.     //调用友元函数   
  52.     prdata(G1,B2);  
  53.     prdata(G2,B3);  
  54.     prdata(G3,B1);  
  55. }  

 

 

三、使用友元成员函数访问另一个类

 

  1. #include <iostream.h>   
  2. #include <string.h>   
  3.   
  4. class girl;  
  5. class boy{  
  6.     char *name;  
  7.     int age;  
  8. public:  
  9.     boy(char *N,int A)  
  10.     {   
  11.         name=new char[strlen(N)+1];  
  12.         strcpy(name,N);  
  13.         age=A;  
  14.     }  
  15.     void disp(girl &);      //声明disp()为类boy的成员函数   
  16.     ~boy(){delete name;}  
  17. };   
  18.   
  19. class girl{  
  20.     char *name;  
  21.     int age;  
  22. public:  
  23.     girl(char *N,int A)  
  24.     {   
  25.         name=new char[strlen(N)+1];  
  26.         strcpy(name,N);  
  27.         age=A;  
  28.     }  
  29.     friend void boy::disp(girl &); //声明类boy的成员函数disp()为类girl的友元函数   
  30.     ~girl(){delete name;}  
  31. };  
  32.   
  33. void boy::disp(girl &x)  
  34. {   
  35.     cout<<"boy/'s name is:"<<name<<",age:"<<age<<endl;  //访问本类对象成员   
  36.     cout<<"girl/'s name is:"<<x.name<<",age:"<<x.age<<endl;  //访问友元类对象成员   
  37. }  
  38. void main()  
  39. {   
  40.     boy b("jsfn_dai",25);  
  41.     girl g("PY",18);  
  42.     b.disp(g);  
  43. }  

 

四、友元类

  1. #include <iostream.h>   
  2. #include <string.h>   
  3.   
  4. class girl;  
  5.   
  6. class boy{  
  7.     char *name;  
  8.     int age;  
  9. public:  
  10.     boy(char *n,int d)  
  11.     {   
  12.         name=new char[strlen(n)+1];  
  13.     strcpy(name,n);  
  14.     age=d;  
  15.     }  
  16.     void disp(girl &);  //声明disp()为类boy的成员函数   
  17.     ~boy(){delete name;}  
  18. };  
  19.   
  20. class girl{  
  21.     char *name;  
  22.     int age;  
  23.     friend boy;   //声明类boy是类girl的友元   
  24. public:  
  25.     girl(char *n,int d)  
  26.     {   
  27.         name=new char[strlen(n)+1];  
  28.         strcpy(name,n);  
  29.         age=d;  
  30.     }  
  31.     ~girl(){delete name;}  
  32. };  
  33.   
  34. void boy::disp(girl &x)  //定义函数disp()为类boy的成员函数,也是类girl的友元函数   
  35. {   
  36.     cout<<"boy/'s name is:"<<name<<",age:"<<age<<endl;  
  37.     cout<<"girl/'s name is:"<<x.name<<",age:"<<x.age<<endl;  
  38. }  
  39.   
  40. void main()  
  41. {   
  42.     boy b("jsfn_dai",25);  
  43.     girl g("PY",18);  
  44.     b.disp(g);  
  45. }  


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值