本章所有编程练习的工程源码可在此处下载(点击此链接下载),供大家参考交流!
1. 对Tv和Remote类做如下修改:
a. 让它们互为友元;
b. 在Remote类中添加一个状态变量成员,该成员描述遥控器是处于常规模式还是互动模式;
c. 在Remote中添加一个显示模式的方法;
d. 在Tv类中添加一个对Remote中新成员进行切换的方法,该方法应仅当TV处于打开状态时才能运行。
编写一个小程序来测试这些新特性。
本题是在程序清单15.1,15.2,15.3的基础上进行修改的。在程序清单15.1中,Remote类是Tv类的友元类,而Tv类不是Remote类的友元类,所以将Tv类的声明和定义放在前面;本题要求修改成互为友元,所以谁前谁后已经无关紧要了,我们做一个前向声明就可以解决了。另外,在类声明内部,一定要将互为类友元体现出来。第二个要求时在Remote类中添加一个状态变量成员,描述模式,这个可以参考Tv类的模式来定义。再添加一个显示模式的方法在Remote类中,添加一个修改模式的切换方法在Tv类中,切换之前判断TV是否处于打开状态即可。
于是头文件tv.h代码如下:
// tv.h -- TV and Remote classes
#ifndef TV_H_
#define TV_H_
class Remote;
class Tv
{
friend class Remote;
public:
enum { Off, On };
enum { MinVal, MaxVal = 20 };
enum { Antenna, Cable };
enum { TV, DVD };
Tv(int s = Off, int mc = 125) : state(s), volume(5), maxchannel(mc), channel(2), 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 == Antenna) ? Cable : Antenna; }
void set_input() { input = (input == TV) ? DVD : TV; }
void settings() const;
void change_r_mode(Remote & r);
private:
int state;
int volume;
int maxchannel;
int channel;
int mode;
int input;
};
class Remote
{
friend class Tv;
private:
int mode;
int r_mode;
enum { Regular, Interact};
public:
Remote(int m = Tv::TV, int f = Regular) : mode(m), r_mode(f) {}
bool volup(Tv & t) { return t.volup(); }
bool voldown(Tv & t) { return t.voldown(); }
void onoff(Tv & t) { t.onoff(); }
void chanup(Tv & t) { t.chanup(); }
void chandown(Tv & t) { t.chandown(); }
void set_chan(Tv & t, int c) { t.channel = c; }
void set_mode(Tv & t) { t.set_mode(); }
void set_input(Tv & t) { t.set_input(); }
void show_r_mode() const { std::cout << "Now the remote mode is " << (r_mode == Regular ? "Regular" : "Interact") << ".\n";}
};
inline void Tv::change_r_mode(Remote & r)
{
if (ison())
{
if (r.r_mode == Remote::Regular)
r.r_mode = Remote::Interact;
else
r.r_mode = Remote::Regular;
r.show_r_mode();
}
else
{
std::cout << "The tv is off, please turn it on!\n";
}
}
#endif
在这里我把change_r_mode()函数作为内联函数在头文件里进行了定义,所以实现文件可以完全照搬程序清单15.2,实现文件tv.cpp代码如下:
// tv.cpp -- methods for the Tv class (Remote methods are inline)
#include "stdafx.h"
#include <iostream>
#include "tv.h"
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 == Antenna ? "antenna" : "cable") << endl;
cout << "Input = " << (input == TV ? "TV" : "DVD") << endl;
}
}
对于测试文件,其他的功能我们还按照程序清单15.3来进行