@友元类的作用

友元类的使用方式

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;

}