C++中友元的实例详解
副标题[/!--empirenews.page--]
C++中友元的实例详解 尽管友元被授予从外部访问类的私有部分的权限,但他们并不与面向对象的编程思想相悖;相反他提高了公共接口的灵活性。 一、友元类 友元声明可以位于公有、私有活保护部分、其所在位置无关紧要 我直接贴出一个摘自< c++ primer plus >的例子来演示 c++ 友元类 其中 Remote 为 Tv的友元类。 Tv.h #ifndef TV_H_ #define TV_H_ /*一个类 电视 */ class Tv { public: friend class Remote; //Remote类可以访问Tv Privite 的私有部分 enum { off,on //开关 }; enum { MinVal,MaxVal=20 //音量 }; enum { Antena,Cable //使用的天线、还是电缆 }; enum { TV,DVD //工作模式 }; Tv(int s = off,int mc = 125) :state(s),volume(5),maxchannel(mc),channel(5),mode(Cable),input(TV) {} void onoff() { state = (state == on) ? off : on; } bool ison()const { return state == on; } bool volup(); //增大声音 bool voldown(); //减小声音 void chanup(); //频道 + void chandown();//频道 - void set_mode() { mode = (mode == Antena) ? Cable : Antena; } void set_input() { input = (input == TV) ? DVD : TV; } void settings()const; //显示所有设置 private: int state; // 开或者 关 int volume; // 音量 int maxchannel; //最大 int channel; //当前频道 int mode; // 广播还是 电缆 int input; //Tv 或者 DVD }; /*Remote 的定义 (遥控器) */ class Remote { private : int mode; // 控制 TV 或 DVD public: Remote(int m = Tv::TV) :mode(m) {} bool volup(Tv & t) { return t.volup(); } bool voldown(Tv & t) { return t.voldown(); } void onoff(Tv & t) { return t.onoff(); } void chanup(Tv & t) { return t.chanup(); } void chandown(Tv & t) { return t.chandown(); } void set_chan(Tv &t,int c) { t.channel = c; } //访问了Tv的私有成员 void set_mode(Tv &t) { t.set_mode(); } void set_input(Tv &t) { t.set_input(); } }; #endif // TV_H_ Tv.cpp #include "stdafx.h" #include "Tv.h" #include <iostream> bool Tv::volup() { if (volume < MaxVal) { volume++; return true; } else { return false; } } bool Tv::voldown() { if (volume > MinVal) { volume--; return true; } else { return false; } } void Tv::chanup() { if (channel < maxchannel) channel++; else channel = 1; } void Tv::chandown() { if (channel > 1) channel--; else channel = maxchannel; } void Tv::settings() const { using std::cout; using std::endl; cout << "TV is " << (state == off ? "off" : "on") << endl; if (state == on) { cout << "Volume setting =" << volume << endl; cout << "Channel setting = " << channel << endl; cout << "Mode = " << (mode == Antena ? "antenna" : "cable") << endl; cout << "Input = " << (input == TV ? "TV" : "DVD") << endl; } } 测试代码: #include "stdafx.h" #include "tv.h" #include <iostream> int main() { using std::cout; Tv s42; cout << "Initial settings for 42 " Tv: n"; s42.settings(); s42.onoff(); s42.chanup(); cout << " n Adjusted settings for 42 " Tv: n"; s42.chanup(); cout << "n Adjusted settings for 42 " Tv: n"; s42.settings(); Remote grey; grey.set_chan(s42,10); grey.volup(s42); grey.volup(s42); cout << " n s42 " settings after using remote: n"; s42.settings(); Tv s58(Tv::on); s58.set_mode(); grey.set_chan(s58,58); cout << " n s58 " setting: n"; s58.settings(); system("pause"); return 0; } 运行结果: Initial settings for 42 " Tv: TV is off Adjusted settings for 42 " Tv: Adjusted settings for 42 " Tv: TV is on Volume setting =5 Channel setting = 7 Mode = cable Input = TV s42 " settings after using remote: TV is on Volume setting =7 Channel setting = 10 Mode = cable Input = TV s58 " setting: TV is on Volume setting =5 Channel setting = 58 Mode = antenna Input = TV 请按任意键继续. . . 上述代码中将Remote类设置成为了Tv类的友元类,但事实上我们看到:唯一访问Tv的成员的方法是void set_chan(Tv &t,int c) { t.channel = c; } ,因此它是唯一需要友元的方法。因此不必让整个类成为友元,这就引出了我们下面要讲的的友元成员函数。 二、友元成员函数 我们要再Tv中将Remote::set_chan()设置成友元: clas Tv { friend void Remote::set_chan(Tv & t,int c ) ; } 然而要使编译器能够处理这条语句,它必须知道Remote的定义。否则,它无法知道Remote是一个类。而 set_chan是这个类的方法。这意味着应将Remote的定义放到Tv的定义前面。Remote的方法提到了Tv对象,而意味着Tv定义应当位于Remote定义之前,避开这种循环依赖的方法是,使用前向声明。 class Tv ; //前向声明 class Remote{...} class Tv {...} 这里还有一个麻烦就是: Remote 包含了内联代码例如:void onoff(Tv &t) {t.onoff();}; (编辑:淮安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |