@友元类的作用
友元类的使用方式
friend class Remote;
使用类似于声明友元函数的语法来声明一个友元类
友元类的作用
引入
当你使用电视机时,开关电视机以及换台调声音都是通过遥控器来完成的,我们不可以直接通过电视机来
调整它的属性。从这里就可以体会到,电视机为遥控器提供了可以修改其私有化属性的接口,而遥控器为
我们提供了可以**间接**或**直接**修改电视机属性的接口。
间接的含义
而这个间接的含义是怎么实现的呢?使用一个代码示例来体会:
bool volup(Tv& t) {
return t.volup(); }
这里通过了一个委托的关系,遥控器将具体的实现交给了电视机中的代码体来处理
在这里,其实并没有使用到友元类真正的用途,这里只是调用了电视机类的接口来改变电视机的私有
属性。
直接的含义
依旧是用代码示例来体会:
void set_chan(Tv& t, int c) {
t.channel = c; }
这里的channel是电视机的私有属性
遥控器直接修改了电视机的私有属性,而不是通过电视机的接口来间接修改
由此引出了友元类主要的作用:
友元类的作用
若一个类是另一个类的友元类,那么这个类可以直接访问另一个类的私有属性和方法
全部代码示例
#pragma once
class Tv {
public:
friend class Remote;
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 setting() const;
private:
int state; //on orr off
int volume;
int maxchannel; //maximum number of channels
int channel; //current channel setting
int mode;
int input;
};
class Remote {
private:
int mode;
public:
Remote(int m = Tv::TV) :mode(m) {
} //全部是inline函数
bool volup(Tv& t) {
return t.volup(); } //组合关系
bool vpodown(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(); }
};
#include"tv.h"
#include<iostream>
#include<string>
using namespace std;
bool Tv::volup() {
if (volume < MaxVal) {
volume++;
return true;
}
return false;
}
bool Tv::voldown() {
if (volume > MinVal) {
--volume;
return true;
}
return false;
}
void Tv::chanup() {
if (channel < maxchannel) {
channel++;
}
else {
channel = 1;
}
}
void Tv::chandown() {
if (channel > 1) {
channel++;
}
else {
channel = maxchannel;
}
}
void Tv::setting() const {
cout << "Tv is" << ((state == off) ? "off" : "on") << endl;
if (state == on) {
cout << "volume setting = " << volume << endl;
cout << "channel setting = " << channel << endl;
cout << "made = " << ((mode == Antenna) ? "antenna" : "cable") << endl;
cout << "input = " << (input == TV ? "TV" : "DVD") << endl;
}
}
#include<iostream>
#include"tv.h"
using namespace std;
int main() {
Tv s42;
cout << "Initial settings for 42\" TV :" << endl;
s42.setting();
s42.onoff();
s42.chanup();
cout << "\nAdjust settings for 42\" TV : " << endl;
s42.setting();
Remote grey;
grey.set_chan(s42, 10);
grey.volup(s42);
grey.volup(s42);
cout << "\n42\"settings after using remote : " << endl;
s42.setting();
Tv s58(Tv::on);
s58.set_mode();
grey.set_chan(s58, 28);
cout << "\n58\" settings : " << endl;
s58.setting();
return 0;
}