c++ primer plus 第15章友,异常和其他:友元类
c++ primer plus 第15章友,异常和其他:友元类
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:友元类
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- c++ primer plus 第15章友,异常和其他:友元类
- 15.1 友元
- 15.1.1 友元类
- 程序清单 15.1 tv.h
- 程序清单 15.2 tv.cpp
- 总结
15.1 友元
本书前面的一些示例将友元函数用于类的扩展接口中,类并非只能拥有友元函数,也可以将类作为友元。在这种情况下,友元类的所有方法都可以访问原始类的私有成员和保护成员。另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元。哪些函数、成员函数或类为友元是由类定义的,而不能从外部强加友情。因此,尽管友元被授予从外部访问类的私有部分的权限,但它们并不与面向对象的编程思想相悖;相反,它们提高了公有接口的灵活性。
15.1.1 友元类
什么时候希望一个类成为另一个类的友元呢?我们来看一个例子。假定需要编写一个模拟电视机和遥控器的简单程序。决定定义一个Tv类和一个 Remote类,来分别表示电视机和遥控器。很明显,这两个类之间应当存在某种关系,但是什么样的关系呢?遥控器并非电视机,反之亦然,所以公有继承的is-a关系并不适用。遥控器也非电视机的一部分,反之亦然,因此包含或私有继承和保护继承的 has-a关系也不适用。事实上,遥控器可以改变电视机的状态,这表明应将 Romote 类作为Tv类的一个友元。首先定义Tv类。可以用一组状态成员(描述电视各个方面的变量)来表示电视机。下面是一些可能的状态:
- 开/关;
- 频道设置;
- 音量设置;
- 有线电视或天线调节模式;
- TV 调谐或 A/V 输入。
- 调节模式指的是,在美国,对于有线接收和 UHF 广播接收,14频道和14频道以上的频道间隔是不同的。输入选择包括TV(有线TV或广播TV)和 DVD。有些电视机可能提供更多的选择,如多种 DVD/蓝光输入,但对于这个示例的目的而言,这个清单足够了。
另外,电视机还有一些不是状态变量的参数。例如,可接收频道数随电视机而异,可以包括一个记录
这个值的成员。接下来,必须给类提供一些修改这些设置的方法。当前,很多电视机都将控件藏在面板后面,但大多数电视机还是可以在不使用遥控器的情况下进行换台等工作的,通常只能逐频道换台,而不能随意选台。同样,通常还有两个按钮,分别用来增加和降低音量。
遥控器的控制能力应与电视机内置的控制功能相同,它的很多方法都可通过使用Tv方法来实现。另外,遥控器通常都提供随意选择频道的功能,即可以直接从2频道换到20频道,并不用逐次切换频道。另很多遥控器都有多种工作模式,如用作电视控制器和 DVD遥控器。外,这些考虑因素表明,定义应类似于程序清单 15.1。定义中包括一些被定义为枚举的常数。下面的语句使 Remote 成为友元类:
friend class Remote;友元声明可以位于公有、私有或保护部分,其所在的位置无关紧要。由于Remote类提到了Tv类,所以编译器必须了解 Tv 类后,才能处理 Remote 类,为此,最简单的方法是首先定义 Tv类。也可以使用前向声明(forward delaration),这将稍后介绍。
程序清单 15.1 tv.h
// tv.h -- Tv and Remote classes
#ifndef TV_H_
#define TV_H_class Tv
{
public:friend class Remote; // Remote can access Tv private partsenum {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; // display all settings
private:int state; // on or offint volume; // assumed to be digitizedint maxchannel; // maximum number of channelsint channel; // current channel settingint mode; // broadcast or cableint input; // TV or DVD
};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 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();}
};
#endif
在程序清单15.1中,大多数类方法都被定义为内联的。除构造函数外,所有的Romote方法都将一个Tv 对象引用作为参数,这表明遥控器必须针对特定的电视机。程序清单15.2列出了其余的定义。音量设置函数将音量成员增减一个单位,除非声音到达最大或最小。频道选择函数使用循环方式,最低的频道设置为1,它位于最高的频道设置maxchannel之后。
很多方法都使用条件运算符在两种状态之间切换:
void onoff(){state=(state ==On)? ff :On;
如果两种状态值分别为tnue(1)和false(0),则可以结合使用将在附录E讨论的按位异或和赋值运算符(^=)来简化上述代码:
void onoff()state^=1;
程序清单 15.2 tv.cpp
// tv.cpp -- methods for the Tv class (Remote methods are inline)
#include <iostream>
#include "tv.h"bool Tv::volup()
{if (volume < MaxVal){volume++;return true;}elsereturn false;
}
bool Tv::voldown()
{if (volume > MinVal){volume--;return true;}elsereturn false;
}void Tv::chanup()
{if (channel < maxchannel)channel++;elsechannel = 1;
}void Tv::chandown()
{if (channel > 1)channel--;elsechannel = 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是一个简短的程序,可以测试一些特性。另外,可使用同一个遥控器控制两台不同的电视机。
//use_tv.cpp -- using the Tv and Remote classes
#include <iostream>
#include "tv.h"int main()
{using std::cout;Tv s42;cout << "Initial settings for 42\" TV:\n";s42.settings();s42.onoff();s42.chanup();cout << "\nAdjusted settings for 42\" TV:\n";s42.settings();Remote grey;grey.set_chan(s42, 10);grey.volup(s42);grey.volup(s42);cout << "\n42\" settings after using remote:\n";s42.settings();Tv s58(Tv::On);s58.set_mode();grey.set_chan(s58,28);cout << "\n58\" settings:\n";s58.settings();// std::cin.get();return 0;
}
下面是程序清单15.1~程序清单15.3组成的程序的输出:

总结
这个练习的主要目的在于表明,类友元是一种自然用语,用于表示一些关系。如果不使用某些形式的友元关系,则必须将Tv类的私有部分设置为公有的,或者创建一个笨拙的、大型类来包含电视机和遥控器。这种解决方法无法反应这样的事实,即同一个遥控器可用于多台电视机。
相关文章:
c++ primer plus 第15章友,异常和其他:友元类
c primer plus 第15章友,异常和其他:友元类 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:友元类 提示:写完文章后,目录可以自动生成,如何生成可参考右边的…...
面试题002-Java-Java集合
面试题002-Java-Java集合 目录 面试题002-Java-Java集合题目自测题目答案1. 说说 List,Set,Map 三者的区别?三者底层的数据结构?2. 有哪些集合是线程不安全的?怎么解决呢?3. 比较 HashSet 、LinkedHashSet 和 TreeSet 三者的异同&…...
数组越界情况
数组越界情况...
工作日常学习记录
使用情景 今天开发上遇到一个搜索的需求,要求可以多选,模糊查询。我首先和前端沟通,前端多选后使用逗号分隔,拼成字符串传输给我,我后端再进行具体的处理。 具体处理 初步构想 由于需要查询的字段也是一个长的字符…...
C#中的容器
1、数组 数组是存储相同类型元素的固定大小的顺序集合 声明数组时,必须指定数组的大小 2.数组的插入和删除数据比较麻烦,但是查询比较快 2、动态数组(ArrayList) 动态数组:可自动调节数组的大小 可以存储任意类型数…...
rust + mingw安装教程
0. 说明 windows上安装rust时,需要在电脑上安装C/C构建工具。推荐的的两种工具链可以选择: visual studio build toolsmingw 官方推荐使用visual studio,若你的电脑上已经安装了visual studio,则无需再安装,直接安装…...
【sqlite3】联系人管理系统
SQLite3实现简单的联系人管理系统 有关sqlite3的基础知识请点击:SQLite3的使用 效果展示: 创建一个名为contacts.db的数据库 首先,我们需要创建一个名为contacts.db的数据库,并建立一个名为"contact"的表࿰…...
秋招Java后端开发冲刺——并发篇2(JMM与锁机制)
本文对Java的内存管理模型、volatile关键字和锁机制进行详细阐述,包括synchronized关键字、Lock接口及其实现类ReentrantLock、AQS等的实现原理和常见方法。 一、JMM(Java内存模型) 1. 介绍 JMM定义了共享内存中多线程程序读写操作的行为规…...
记录一次Chrome浏览器自动排序ajax请求的JSON数据问题
文章目录 1.前言2. 为什么会这样?3.如何解决? 1.前言 作者作为新人入职的第一天,mentor给了一个维护公司运营平台的小需求,具体需求是根据运营平台的某个管理模块所展示记录的某些字段对展示记录做排序。 第一步: myb…...
【嵌入式——FreeRTOS】任务
【嵌入式——FreeRTOS】任务 任务创建和删除动态方式创建任务静态方式创建任务 删除任务任务切换调度器任务切换流程 任务挂起任务恢复相关API函数 任务创建和删除 动态方式创建任务 任务的任务控制块以及任务的栈空间所需的内存,均由freeRTOS从freeRTOS管理的堆中…...
网关,路由器,交换机
一、网关 (Gateway) 是一种设备,用于连接不同网络,能够转发数据包并翻译协议,允许不同类型的网络通信。网关通常工作在OSI模型的应用层或传输层,提供连接和路由服务。 应用场景例子: 在企业网络中,网关可…...
sublime 3 背景和字体颜色修改
sublime 4 突然抽风,每次打开都显示 “plugin_host-3.3 has exited unexpectedly, some plugin functionality won’t be available until Sublime Text has been restarted” 一直没调好,所以我退回到sublime 3了。下载好了软件没问题,但是一…...
leetcode 403周赛 包含所有1的最小矩形面积||「暴力」
3197. 包含所有 1 的最小矩形面积 II 题目描述: 给你一个二维 二进制 数组 grid。你需要找到 3 个 不重叠、面积 非零 、边在水平方向和竖直方向上的矩形,并且满足 grid 中所有的 1 都在这些矩形的内部。 返回这些矩形面积之和的 最小 可能值。 注意…...
Stable Diffusion web UI 插件
2024.7.3更新,持续更新中 如果需要在linux上自己安装sd,参考:stable diffusion linux安装 插件复制到 /stable-diffusion-webui/extensions 目录下,然后重新启动sd即可 一、插件安装方法 每种插件的安装方法可能略有不同…...
深度学习中的反向传播算法的原理
深度学习中的反向传播算法的原理,以及如何计算梯度 反向传播算法(Backpropagation)是深度学习中最核心的优化技术之一,用于训练神经网络。它基于链式法则,通过从输出层逆向计算误差并逐层传递到输入层来更新模型参数&…...
身处奇瑞看三星:既“开卷“又“起火“,却更难受了
三星"起火" 这几天奇瑞的事情,让大家破防了,纷纷表示国内的就业市场环境普遍恶劣。 那我们转个眼,看看海外企业的情况。 最近一周,三星频频登上新闻,颇有"起火"之势。 在刚步入下半年的 7 月 1 日…...
系统架构设计师教程(清华第2版)<第1章 绪论>解读
系统架构设计师教程 第一章 绪论 1.1 系统架构概述1.1.1 系统架构的定义及发展历程1.1.2 软件架构的常用分类及建模方法1.1.3 软件架构的应用场景1.1.4 软件架构的发展未来1.2 系统架构设计师概述1.2.1 架构设计师的定义、职责和任务1.2.2 架构设计师应具备的专业素质1.3 如何成…...
Vue + Element UI + JSEncrypt实现简单登录页面
安装依赖 npm install jsencrypt --save局部引入 import JSEncrypt from jsencrypt/bin/jsencrypt;登录页面index.vue <template><div class"loginbody"><div class"logindata"><div class"logintext"><h2>Wel…...
从“关注流”到“时间线”,搜狐给内容加信任价值
文 | 螳螂观察 作者 | 易不二 在近日第十六季搜狐新闻马拉松活动中,搜狐新闻APP的“时间线”功能备受瞩目。不仅开幕式现场竖了一块“左手时间线,右手关注流”的路牌,张朝阳也着重强调了“时间线”产品的互动方式:“关注是基础&…...
vscode的一些使用问题
vscode使用技巧 1、快捷键(1)打开命令面板(2)注释(3)删除行(4)上下移动光标(5)光标回退(6)复制行(7)插入空白行…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
