友元简介:友元函数,友元类和友元成员函数
来源:互联网 发布:微信投票软件 编辑:程序博客网 时间:2024/06/09 17:53
友元简介:
C++为了保证类的封装性,使私有部分和保护部分对外不可见,公有部分提供唯一的访问途径。(基类的保护部分在public,protected方式的派生类中,也对外提供访问途径,在派生类中访问权限同公有部分)。
但这样的限制太严格,以至于不适合特定的编程,因此,C++提供了另一种形式的访问权限,即友元。使得可以访问友元所在类的私有部分和保护部分。友元与位于类的public,private,protected的位置无关,均可访问所在类的私有部分和保护部分。
友元在一定程度上破坏了类的封装性,但同时也是类的接口操作更加灵活。
友元分为3中:
1.友元函数
2.友元类
3.友元成员函数
1.友元函数
可以将单独一函数作为一个类的友元函数,使这个函数具有访问 后者私有成员和保护成员的能力。
例子:
2.友元类
将一个类声明为另一个类的友元,这样作为友元的类 就可以访问 后者的私有成员和保护成员了。(无论友元类声明在后一个类的公有部分还是 私有部分,其所在位置无关紧要)
使用场合:如 电视机与遥控的关系。不是 has-a 的关系,因为 一台遥控可以控制多个电视。同时更不是 a kind of的关系。但是 遥控可以改变 电视机的状态,此种情况用友元来实现,更合适,即让遥控类作为电视机类的友元,可以更改其私有成员。
例子:
3.友元成员函数
亦可以将一个类的成员函数作为另一个类的友元函数,仅使类的这个成员函数具有访问后者私有成员和保护成员的能力,其他类成员无这个能力。
如上例中,
#1 依然为使用Tv类的公有接口来实现功能。 #2,#3直接访问 私有部分和保护部分,因此可只将 #2,#3的类成员函数声明为Tv类的友元,Remote类的其他成员 只用通过公有接口来访问Tv类。
这样做两个注意项:
1.前向声明的使用。
2.类定义置后。(保证当一个类的定义中 使用另一个类的方法时,所用的方法在此定义之前,已声明)。
C++为了保证类的封装性,使私有部分和保护部分对外不可见,公有部分提供唯一的访问途径。(基类的保护部分在public,protected方式的派生类中,也对外提供访问途径,在派生类中访问权限同公有部分)。
但这样的限制太严格,以至于不适合特定的编程,因此,C++提供了另一种形式的访问权限,即友元。使得可以访问友元所在类的私有部分和保护部分。友元与位于类的public,private,protected的位置无关,均可访问所在类的私有部分和保护部分。
友元在一定程度上破坏了类的封装性,但同时也是类的接口操作更加灵活。
友元分为3中:
1.友元函数
2.友元类
3.友元成员函数
1.友元函数
可以将单独一函数作为一个类的友元函数,使这个函数具有访问 后者私有成员和保护成员的能力。
例子:
class Tv{ private: int channel; int mode; protected: int vol; public: .... friend void settings(int c, Tv& t) { t.channel = c; t.mode = c;} //直接访问对类对象的 私有成员和保护成员}
2.友元类
将一个类声明为另一个类的友元,这样作为友元的类 就可以访问 后者的私有成员和保护成员了。(无论友元类声明在后一个类的公有部分还是 私有部分,其所在位置无关紧要)
使用场合:如 电视机与遥控的关系。不是 has-a 的关系,因为 一台遥控可以控制多个电视。同时更不是 a kind of的关系。但是 遥控可以改变 电视机的状态,此种情况用友元来实现,更合适,即让遥控类作为电视机类的友元,可以更改其私有成员。
例子:
class Tv { private: int channel; int mode; protected: int vol; public: void set_mode(); friend class Remote; } class Remote { private: int mode; public: void set_mode(Tv &t) { t.set_mode(); } //#1 void set_vol(int c, Tv&t) {t.vol= c;}// #2 访问 类的保护成员 void set_chan(int c, Tv&t) {t.channel = c;} // #3 访问 类的私有成员 }
3.友元成员函数
亦可以将一个类的成员函数作为另一个类的友元函数,仅使类的这个成员函数具有访问后者私有成员和保护成员的能力,其他类成员无这个能力。
如上例中,
class Remote{ ... public: void set_mode(Tv &t) { t.set_mode(); } //#1 .....}
#1 依然为使用Tv类的公有接口来实现功能。 #2,#3直接访问 私有部分和保护部分,因此可只将 #2,#3的类成员函数声明为Tv类的友元,Remote类的其他成员 只用通过公有接口来访问Tv类。
这样做两个注意项:
1.前向声明的使用。
2.类定义置后。(保证当一个类的定义中 使用另一个类的方法时,所用的方法在此定义之前,已声明)。
需小心排列各种声明和定义的顺序。
例:
class Tv; //Note 1:前向声明 因为Note 2 处 用到Tv &t,需告诉编译器,此处Tv 为类class Remote{private: int mode;public: enum{Off, On}; enum{MinVal, MaxVal = 20}; enum{Antenna, Cable}; enum{TV, VCR};public: Remote(int m = TV):mode(m){} void onoff(Tv &t); //Note 2: error #1 {t.onff();} 因为在此之前未见到Tv 类的 onoff()成员函数,所以此定义需后置 void vol_up(Tv &t); void vol_down(Tv &t); void channel_up(Tv &t); void channel_down(Tv &t); void set_mode(Tv &t); void set_input(Tv &t); void set_chan(Tv &t, int c);};class Tv{private: int state; int channel; int maxchannel; int mode; int input; int volume;public: friend void Remote::set_chan(Tv &t,int c);// Note:3 声明 友元成员函数 enum{Off, On}; enum{MinVal, MaxVal = 20}; enum{Antenna, Cable}; enum{TV, VCR}; Tv(int s = Off, int mc = 100):state(s),maxchannel(mc),volume(5), input(TV),mode(Antenna),channel(1){} bool ison()const {return (state== On ? TRUE:FALSE);} void onoff() {state = (state == On ? Off:On);} void vol_up(); void vol_down(); void channel_up(); void channel_down(); void set_mode() {mode = (mode == Antenna ? Cable:Antenna);} void set_input() {input = (input == TV ? VCR : TV);} void settings();};void Tv::vol_up(){ if (volume == MaxVal) { volume = MinVal; } else volume++;}void Tv::vol_down(){ if (volume == MinVal) { volume = MaxVal; } else volume--;}void Tv::channel_up(){ if (channel == maxchannel) { channel = 1; } else channel++;}void Tv::channel_down(){ if (channel == 1) { channel = maxchannel; } else channel--;}void Tv::settings(){ cout<<"Tv is "<<(state== On ? "on":"off")<<endl; if (state == On) { cout<<"channel volume mode input\n"; cout<<setw(7)<<channel<<setw(8)<<volume <<setw(10)<<(mode== Antenna ?"Antenna":"cable") <<setw(7)<<(input== TV ? "TV":"Cable")<<endl; } }inline void Remote::onoff(Tv&t) {t.onoff();} //Note 4: Remote 类方法定义置于 Tv类方法声明之后inline void Remote::vol_up(Tv&t) {t.vol_up();}inline void Remote::vol_down(Tv&t) {t.vol_down();}inline void Remote::channel_up(Tv&t) {t.channel_up();}inline void Remote::channel_down(Tv&t) {t.channel_down();}inline void Remote::set_mode(Tv&t) {t.set_mode();}inline void Remote::set_input(Tv&t) {t.set_input();}inline void Remote::set_chan(Tv&t, int c){t.channel= c;}
讨论此处使用的为
class Tv;class Remote{}class TV{}
的方法,能否交换次序?改为:
class Remote;class Tv{}class Remote{}
答案不能。 Tv 的声明有friend void Remote::set_chan(Tv &t,int c); 而在此前未见到 Remote类的声明(即含有set_chan(Tv &t,int c); 这一成员函数)。因此,在Tv的类定义之前,需先见到Remote的类定义。
- 友元简介:友元函数,友元类和友元成员函数
- C++友元简介:友元函数,友元类和友元成员函数
- 友元简介:友元函数,友元类和友元成员函数
- 友元成员函数
- 友元类,友元成员函数,
- 友元(友元函数、友元类和友元成员函数) C++
- 友元函数简介
- 友元函数、友元类、友元成员函数
- 友元函数、友元类、友元成员函数
- C++友元函数、友元类、友元成员函数
- 体验友元成员函数
- 7.31友元成员函数
- c++友元成员函数
- 静态成员函数和友元
- 分清成员函数,非成员函数和友元函数
- 成员函数 非成员函数和友元函数
- 成员函数 非成员函数和友元函数
- 成员函数、非成员函数和友元函数介绍
- Groovy的list和map
- posix 多线程有感--线程
- find 和 grep 的结合使用
- Hadoop命令操作
- 获取 ssh 公钥命令
- 友元简介:友元函数,友元类和友元成员函数
- appledoc相关内容汇总(非原创)
- 【linux】——ubuntu server 12.04重启不能上网的问题
- IIS7 FTP 设置
- Ext.Net 1.x_Ext.Net.Windows的IFrame用法
- 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集
- C#实现注册码 CPU序列号,生成机器码 生成注册码 判断是否注册
- Oracle 外键约束
- 推荐一个学习MongoDB数据库的博文链接