2 class Remote {...};
3 class Tv {...};
?
?
能否这样:
?
1 class Remote ;//前向声明
2 class Tv {...};
3 class Remote {...};
?
?
这样做是不可以的,因为编译器在Tv类的声明中看到Remote的一个方法被声明为Tv类的友元之前,应该先看到Remote类的声明和set_chan()方法的声明,如果像上面这样,虽然看到了Remote类的声明,但是看不到set_chan()方法的声明。
?
还有一个问题,比如在Remote声明中包含如下内联函数:
?
void onoff(Tv & t) {t.onoff();}
?
也就是说,在声明这个方法的时候,就给出了它的定义,即调用了Tv的一个方法,而Tv的声明(不是前向声明哦)是放在Remote声明后面的,显然会有问题。所以解决方法是,在Remote声明中只包含方法的声明,而不去定义,将实际的定义放在Tv类之后,即
?
void onoff(Tv & t) ;
?
编译器在检查该原型时,需要知道Tv是一个类,而前向声明提供了这种信息,当编译器到达真正的方法定义时,它已经读取了Tv类的声明,关于函数内联,后面可以使用inline关键字声明。
?
给出修改后的头文件:
?
复制代码
?1 /*Tv and Remote classes*/
?2 #ifndef TV_H_
?3 #define TV_H_
?4?
?5 class Tv;
?6?
?7 class Remote
?8 {
?9 public:
10 ? ? enum State{Off, On}; ? ?
11 ? ? enum {MinVal, MaxVal = 20};
12 ? ? enum {Antenna, Cable};
13 ? ? enum {TV, DVD};
14 private:
15 ? ? int mode;
16 public:
17 ? ? //只声明,不定义
18 ? ? Remote(int m =TV) : mode(m) {}
19 ? ? bool volup(Tv & t);
20 ? ? bool voldown(Tv & t);
21 ? ? void onoff(Tv & t);
22 ? ? void chanup(Tv & t);
23 ? ? void chandown(Tv & t);
24 ? ? void set_chan(Tv & t, int c);
25 ? ? void set_mode(Tv & t);
26 ? ? void set_input(Tv & t);
27 };
28?
29 class Tv
30 {
31 public:
32 ? ? friend void Remote::set_chan(Tv & t, int c); //声明谁是自己的“好基友”(友元)
33 ? ? enum State{Off, On}; ? ?
34 ? ? enum {MinVal, MaxVal = 20};
35 ? ? enum {Antenna, Cable};
36 ? ? enum {TV, DVD};
37?
38 ? ? Tv(int s = Off, int mc =125) : state(s), volume(5),?
39 ? ? ? ? maxchannel(mc), channel(2), mode(Cable), input(TV) {};
40 ? ? void onoff(){state = (state == On)? Off : On;}
41 ? ? bool ison() const {return state == On;}
42 ? ? bool volup();
43 ? ? bool voldown();
44 ? ? void chanup();
45 ? ? void chandown();
46 ? ? void set_mode() {mode = (mode == Antenna) ? Antenna : Cable;}
47 ? ? void set_input() {input = (input = TV) ? DVD : TV;}
48 ? ? void settings() const; //显示所有设置
49 private:
50 ? ? int state; ? ? ?//开或者关
51 ? ? int volume; ? ? //音量
52 ? ? int maxchannel; //最多频道数
53 ? ? int channel; ? ?//当前频道号
54 ? ? int mode; ? ? ? ?//Antenna或者Cable模式
55 ? ? int input; ? ? ?//TV或者DVD输入
56 };
57?
58 //Remote方法定义为内联函数
59 inline bool Remote::volup(Tv & t) {return t.volup();}
60 inline bool Remote::voldown(Tv & t) {return t.voldown();}
61 inline void Remote::onoff(Tv & t) {t.onoff();}
62 inline void Remote::chanup(Tv & t) {t.chanup();}
63 inline void Remote::chandown(Tv & t) {t.chandown();}
64 inline void Remote::set_chan(Tv & t, int c) {t.channel = c;}
65 inline void Remote::set_mode(Tv & t) {t.set_mode();}
66 inline void Remote::set_input(Tv & t) {t.set_input();}
67 #endif