第 15 章 友元、异常和其它

15.1. 友元

友元函数用于类的扩展接口 中,类中不仅可以使用友元函数,也可以将类作为友元。

友元类的所有方法都可以访问原始类的私有成员保护成员

在一个类中将另一个类声明为友元。

15.1.1 友元类

什么时候希望一个类成为另一个类的友元呢?

举个例子:模拟电视机和遥控器的简单程序。要知道遥控器并非电视机,故公有继承is-a关系并不适用。遥控器也非电视机的一部分,因此包含或者私有继承和保护继承的has-a关系也不适用。事实上,遥控器可以改变电视机的状态,这就表明遥控器类应当作为电视类的一个友元。

按照如上描述,决定编写一个模拟电视机和遥控器的简单程序。

首先定义Tv类,可以用一组状态成员(描述电视各个方面的变量)来表示电视机。下面是一些可能的状态:

  • 开/关;
  • 频道设置;
  • 音量设置;
  • 有线电视或天线调节模式
  • TV调谐或A/V输入

ps:当前的电视机都将控件藏在面板之后(换台只能逐频道换),遥控器的控制能力必须得与电视机内置的控制功能相同,它的大部分方法是根据Tv内置的方法来进行改造的,就比如刚刚所说的利用电视机控制面板切台只能逐个频道切换,遥控器在此基础上进行改造,使其能够按个人意愿进行切台。

为什么说遥控器大部分方法是根据Tv方法进行改造的呢?因为遥控器本身还有其他一些自己单独的功能,就好比如切换工作模式,一种拿来控制电视机、一种拿来控制DVD。

下面语句使得Remote成为友元类

friend class Remote;

友元声明可以位于公有、私有或者保护部分,其所在的位置无关紧要。

遥控器是后来者,所以编译器必须了解电视(Tv)类后,才能处理遥控器(Remote)类。

下面开始模拟遥控器操控电视机,或者电视机自己操控自己:

1、头文件

//
// Created by e on 2022/10/18.
//#ifndef TEST_TV_H
#define TEST_TV_Hclass Tv {
public:friend class Remote; // Remote can access Tv private partsenum {Off, On};enum {MinVal, MaxVal = 20};enum {Antenna, Cable}; // Antenna->天线 Cable->有线enum {TV, DVD};Tv(int s = Off, int mc = 125) : state(s), volume(5),maxChannel(mc), curChannel(2), mode(Cable), input(TV) { }void onOff() {state = (state == On) ? Off : On;}bool isOn() const {return state == On;}bool volUp();   //声音提高bool volDown(); //声音降低void channelUp();  //频道往后调void channelDown();   //频道往前调void setMode() {mode = (mode == Antenna) ? Cable : Antenna;}void setInput() {input = (input == TV) ? DVD : TV;}void showSettings() const;   //display all TV settings.private:int state;      //on or offint volume;     //assumed to be digitized-->假设是用数字大小代表音量大小int maxChannel; //maximum number of channelsint curChannel; //current channel settingint input;      //TV or DVDint mode;       //broadcast or cable
};class Remote {
private:int mode;       //controls TV or DVD
public:Remote(int m = Tv::TV) : mode(m) { }bool volUp(Tv &t) { return t.volUp(); }bool volDown(Tv &t) { return t.volDown(); }void onOff(Tv &t) { t.onOff(); }void channelUp(Tv &t) { t.channelUp(); }void channelDown(Tv &t) { t.channelDown(); }void setChannel(Tv &t, int c) { t.curChannel = c; }void setMode(Tv &t) { t.setMode(); }void setInput(Tv &t) { t.setInput(); }
};#endif //TEST_TV_H

2、源文件

//
// Created by e on 2022/10/18.
//#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::channelUp() {if (curChannel < maxChannel){curChannel++;}else{curChannel = 1;}
}void Tv::channelDown() {if (curChannel > 1){curChannel--;}else{curChannel = maxChannel;}
}void Tv::showSettings() const {using std::cout;using std::endl;cout << "TV is " << (state == On ? "On" : "Off") << endl;if (state == On){cout << "Volume setting = " << volume << endl;cout << "Channel setting = " << curChannel << endl;cout << "Input settng = " << (input == TV ? "TV" : "DVD") << endl;cout << "Mode setting = " << (mode == Antenna ? "Antenna":"Cable") << endl;}
}

3、执行文件

#include <iostream>
#include "tv.h"int main(){using std::cout;Tv s42;cout << "Initial settings for 42\" TV:\n";s42.showSettings();s42.onOff();s42.channelUp();cout << "\n Adjusted settings for 42\" TV:\n";s42.showSettings();Remote grey;grey.setChannel(s42,10);grey.volUp(s42);grey.volUp(s42);cout << "\n42\" settings after using remote:\n";s42.showSettings();Tv s58(Tv::On);s58.setMode();grey.setChannel(s58,28);cout << "\n58\" settings:\n";s58.showSettings();return 0;
}输出:
Initial settings for 42" TV:
TV is OffAdjusted settings for 42" TV:
TV is On
Volume setting = 5
Channel setting = 3
Input settng = TV
Mode setting = Cable42" settings after using remote:
TV is On
Volume setting = 7
Channel setting = 10
Input settng = TV
Mode setting = Cable58" settings:
TV is On
Volume setting = 5
Channel setting = 28
Input settng = TV
Mode setting = Antenna

15.1.2 友元成员函数

上个例子,Remote中大多数方法都是用Tv类的公有接口实现的。这说明这些方法实际上不太需要作为友元,可以直接地说多此一举了。在Remote方法中,setChannel()是直接访问了Tv的私有成员,所以它被设置为友元是很应该的。实际上,可以让一部分的类成员成为另一个类的友元。

⚠️:如果按照上面那样做,必须小心排列各种声明和定义的顺序

如果要将友元类中的特定的类成员解析作为原始类友元,无需将整个类作为友元。

class Tv
{friend void Remote::setChannel(tv & t, int c);...
};

执行以上语句,需要编译器提前知道Remote的定义,所以将类声明为友元时,需要注意❗️:将类(TV)声明放在包含友元类(Remote)的前面。 这种方法称为 前向声明(forward declaration)

class Tv;  // 前向声明
class Remote {...}
class Tv {...};

思考

第十五章 友元、异常和其他相关推荐

  1. 吴恩达《机器学习》第十五章:异常检测

    文章目录 十五.异常检测 15.1 问题的动机 15.2 高斯分布 15.3 算法 15.4 开发和评价一个异常检测系统 15.5 异常检测 VS 监督学习 15.6 选择特征 15.7 多元高斯分布 ...

  2. 【C++ Primer】第十五章 友元、异常和其他 --之一---友元和嵌套类

    一,友元 1)可以将类作为友元,友元类的所有方法都可以访问原始类的私有成员和保护成员. 2)下面例子介绍了 电视类和遥控器类,其中遥控器类为电视类的友元类 3)注意:友元关系不具对称性.即 A 是 B ...

  3. 第十五章 异常检测-机器学习老师板书-斯坦福吴恩达教授

    第十五章 异常检测 15.1 问题动机 15.2 高斯分布 15.3 算法 15.4 完善和评估一个异常检测系统 15.5 异常检测 vs 监督学习 15.6 选择使用的特征 15.7 多元高斯分布 ...

  4. 20190901 On Java8 第十五章 异常

    第十五章 异常 要想创建健壮的系统,它的每一个构件都必须是健壮的. 异常概念 C++的异常处理机制基于 Ada,Java 中的异常处理则建立在 C++的基础之上(尽管看上去更像 Object Pasc ...

  5. 《Windows核心编程》读书笔记二十五章 未处理异常,向量化异常处理与C++异常

    第二十五章  未处理异常,向量化异常处理与C++异常 本章内容 25.1 UnhandledExceptionFilter函数详解 25.2 即时调试 25.3 电子表格示例程序 25.4 向量化异常 ...

  6. Java(第十五章)

    第十五章 一.字符串类String 1.String是一个类,位于java.lang包中 2.创建一个字符串对象的2种方式: String 变量名="值"; String 对象名= ...

  7. 分布式系统概念和设计 第十五章 (1)

    COORDINATION AND AGREEMENT http://www.cdk5.net/wp/ 背景知识点:Reliable failure detector 实际系统中没有reliable f ...

  8. 第十五章 面向对象程序设计

    第十五章 面向对象程序设计 OOP:概述 面向对象程序设计(object-oriented programming)的核心思想是数据抽象.继承和动态绑定. 继承(inheritance): 通过继承联 ...

  9. 第十五章 - 垃圾回收相关算法

    第十五章 - 垃圾回收相关算法 文章目录 第十五章 - 垃圾回收相关算法 1.标记阶段:引用计数算法 1.1 垃圾标记阶段:对象存活判断 1.2 引用计数算法 1.3 小结 2.标记阶段:可达性分析算 ...

  10. 达芬奇密码 第五十五章 第五十六章

    达芬奇密码 第五十五章 第五十六章[@more@] 第五十五章 索菲靠着兰登坐在长沙发上,喝着茶吃着烤饼,享受着食物的美味.雷·提彬爵士微笑着,在炉火前面笨拙地踱来踱去.假肢敲在地面上,发出" ...

最新文章

  1. 成语json_cocos creator实战(2)成语小秀才ts版
  2. Windows事件等待学习笔记(三)—— WaitForSingleObject函数分析
  3. php arrayudiff,php array_udiff工作原理
  4. matlab 图像的色彩强度,图像色彩增强的问题,,,小白给跪,
  5. android 组件路由框架,XRouter:组件化路由框架
  6. 【转】Java学习---内存溢出的排查经历
  7. 句句真研—每日长难句打卡Day12
  8. 【深度学习】学习深度学习的最好方法
  9. jQuery Mobile 中文手册 Ajax开发版(2)
  10. 二十三 NoSqlRedis及其安装
  11. Windows Workflow HOL学习笔记(七):添加一个验证来检查Email参数
  12. 网关串口+EM310
  13. java爬取网易云歌单_爬取网易云音乐所有歌单
  14. 3个极品在线PDF转换成WORD服务网站,比软件给力!
  15. STM32实现NRF24L01通信
  16. Halcon教程二:内置实例程序库
  17. Cocos--叠加打印log
  18. Skyworks Aeronautics宣布获得GEM的1亿美元投资承诺,计划于未来数月内上市
  19. 变色玫瑰html,玫瑰花变色实验
  20. 国家电网职称英语计算机答案,国家电网职称英语题库短文判断

热门文章

  1. 【牛客网】 BM69 把数字翻译成字符串(动态规划C++题解)
  2. 小爬虫。爬取网站多页的通知标题并存取在txt文档里。
  3. 项目上线前验收测试流程
  4. C++学习(一五九)Qt的场景图Scene Graph
  5. Win10 【TITAN Xp】和【TITAN RTX】-【TensorFlow】环境简单总结
  6. A fastandrobust convolutionalneuralnetwork-based defect detection model inproductqualitycontrol-阅读笔记
  7. 计算机和人类处理信息的过程,信息处理的一般过程
  8. 如何获取和发现用户需求
  9. 一文讲透计算机网络的数据链路层
  10. 警方通报“济南1家6口死亡”案:男子杀害亲人后放火跳楼