enum {Off, On}; //
?9 ? ? enum {MinVal, MaxVal};
10 ? ? enum {Antenna, Cable};
11 ? ? enum {TV, DVD};
12?
13 ? ? Tv(int s = Off, int mc =125) : state(s), volume(5),?
14 ? ? ? ? maxchannel(mc), channel(2), mode(Cable), input(TV) {};
15 ? ? void onoff(){state = (state == On)? Off : On;}
16 ? ? bool ison() const {return state == On;}
17 ? ? bool volup();
18 ? ? bool voldown();
19 ? ? void chanup();
20 ? ? void chandown();
21 ? ? void set_mode() {mode = (mode == Antenna) ? Antenna : Cable;}
22 ? ? void set_input() {input = (input = TV) ? DVD : TV;}
23 ? ? void settings() const; //显示所有设置
24 private:
25 ? ? int state; ? ? ?//开或者关
26 ? ? int volume; ? ? //音量
27 ? ? int maxchannel; //最多频道数
28 ? ? int channel; ? ?//当前频道号
29 ? ? int mode; ? ? ? ?//Antenna或者Cable模式
30 ? ? int input; ? ? ?//TV或者DVD输入
31 };
32?
33 class Remote
34 {
35 private:
36 ? ? int mode; ? ? ?//控制是TV或者DVD
37 public:
38 ? ? Remote(int m = Tv::TV) : mode(m) {}
39 ? ? bool volup(Tv & t) {return t.volup();}
40 ? ? bool voldown(Tv & t) {return t.voldown();}
41 ? ? void onoff(Tv & t) {t.onoff();}
42 ? ? void chanup(Tv & t) {t.chanup();}
43 ? ? void chandown(Tv & t) {t.chandown();}
44?
45 ? ? /*此处,友元类成员函数set_chan()访问了原始类Tv的私有成员channel
46 ? ? 即使t是Tv的对象,要知道一个类是不允许对象直接访问私有成员的,此处
47 ? ? 之所以可以,就是因为Remote是Tv“好基友”(友元)的缘故*/
48 ? ? void set_chan(Tv & t, int c) {t.channel = c;}
49?
50 ? ? void set_mode(Tv & t) {t.set_mode();}
51 ? ? void set_input(Tv & t) {t.set_input();}
52 };
53 #endif
复制代码
?
?
?
?
复制代码
?1 #include
?2 #include "tv.h"
?3?
?4 bool Tv::volup()
?5 {
?6 ? ? if (volume < MaxVal)
?7 ? ? {
?8 ? ? ? ? volume++;
?9 ? ? ? ? return true;
10 ? ? }
11 ? ? else
12 ? ? ? ? return false;
13 }
14 bool Tv::voldown()
15 {
16 ? ? if (volume > MinVal)
17 ? ? {
18 ? ? ? ? volume--;
19 ? ? ? ? return true;
20 ? ? }
21 ? ? else
22 ? ? ? ? return false;
23 }
24 void Tv::chanup()
25 {
26 ? ? if (channel < maxchannel)
27 ? ? ? ? channel++;
28 ? ? else
29 ? ? ? ? channel = 1;
30 }
31 void Tv::chandown()
32 {
33 ? ? if (channel > 1)
34 ? ? ? ? channel--;
35 ? ? else
36 ? ? ? ? channel = maxchannel;
37 }
38?
39 void Tv::settings() const
40 {
41 ? ? using std::cout;
42 ? ? using std::endl;
43 ? ? cout << "TV is " << (state == Off ? "Off" : "On") << endl;
44 ? ? if (state == On)
45 ? ? {
46 ? ? ? ? cout << "Volume setting = " << volume << endl;
47 ? ? ? ? cout << "Channel setting = " << channel << endl;
48 ? ? ? ? cout << "Mode = " <
49 ? ? ? ? ? ? (mode == Antenna? "antenna" : "cable") << endl;
50 ? ? ? ? cout << "Input = "?
51 ? ? ? ? ? ? ?<< (input == TV? "TV" : "DVD") << endl;
52 ? ? }
53 }
复制代码
?
?
复制代码
?1 /*usetv*/
?2 #include
?3 #include "tv.h"
?4?
?5 int main()
?6 {
?7 ? ? using std::cout;
?8 ? ? Tv s42;
?9 ? ? cout << "Initial settings for 42\" TV: \n";
10 ? ? s42.settings();
11 ? ? s42.onoff();
12 ? ? s42.chanup();
13 ? ? cout << "\n Adjusted settings for 42\" TV: \n";
14 ? ? s42.chanup();
15 ? ? cout << "\n Adjusted settings for 42\" TV: \n";
16 ? ? s42.settings();
17?
18 ? ? Remote grey;
19?
20 ? ? grey.set_chan(s42, 10);
21 ? ? grey.volup(s42);
22 ? ? grey.volup(s42);
23 ? ? cout << "\n42\" settings after using remote:\n";
24 ? ? s42.settings();
25?
26 ? ? Tv s58(Tv::On);//这反应了一个遥控器可以控制多台电视
27 ? ? s58.set_mode();
28 ? ? grey.set_chan(s58, 28);
29 ? ? cout << "\n58\' settings:\n";
30 ? ? s58.settings();
31 ? ? return 0;
32 }
复制代码
?
?
运行结果:
?
?
?
四、友元成员函数
?
对于上面的例子,大多数Remote方法都是用Tv的共有接口实现的,意味着这些用Tv的共有接口实现的方法不需要作为友元,唯一直接访问Tv成员的Remote方法是Remote::set_chan(),因此它是唯一需要作为友元的方法,所以可以仅让特定的类成员成为另一个类的友元,而不必将整个类成为友元。
?
让Remote::set_chan()成为Tv友元的方法是:
?
class Tv
{
? ? ?friend void Remote::set_chan(Tv & t, int c);
... ??
};
?
?
要处理上述语句,编译器必须知道Remote的定义,所以Remote的定义应该放在Tv定义前面,问题是Remote::set_chan(Tv & t, int c)使用了Tv类的对象,故而Tv的定义应该放在Remote定义前面,这就产生了矛盾。
?
为了解决这个矛盾,需要使用一种叫做前向声明(forward declaration),就是在Remote定义之前插入如下语句:
?
class Tv;
?
即排列次序如下:
?
1 class Tv;//前向声明