【继承】复杂的菱形继承

图片名称

博主首页: 有趣的中国人
 

专栏首页: C++进阶
 


本篇文章主要讲解 菱形继承 的相关内容

目录

1. 继承与友元

2. 继承与静态成员

3. 复杂的菱形继承及菱形虚拟继承

3.1 继承分类

3.2 菱形继承导致的问题

3.3 虚拟继承解决数据冗余的原理

4. 继承和组合的区别


 1. 继承与友元

友元关系不能继承,也就是说,基类的友元函数不能访问子类的保护和私有成员。

class Student;
class Person
{
public:
	friend void Display(const Person& p, const Student& s);
protected:
	string _name = "Jason"; // 姓名
};
class Student : public Person
{
protected:
	int _stuNum; // 学号
};
void Display(const Person& p, const Student& s)
{
	cout << p._name << endl;
    // 此处不能访问
	//cout << s._stuNum << endl;
}
void main()
{
	Person p;
	Student s;
	Display(p, s);
}

2. 继承与静态成员

基类定义了static静态成员,则整个继承体系里面只有一个这样的成员。无论派生出多少个子
类,都只有一个static成员实例
 

我们可以利用这个特性计算构造出了多少个继承的对象,只要在构造函数中每次将静态成员变量自增1即可。

class Person
{
public:
	Person() { ++_count; }
protected:
	string _name; // 姓名
public:
	static int _count; // 统计人的个数。
};

int Person::_count = 0;

class Student : public Person
{
protected:
	int _stuNum; // 学号
};

class Graduate : public Student
{
protected:
	string _seminarCourse; // 研究科目
};

void TestPerson()
{
	Student s1;
	Student s2;
	Student s3;
	Graduate s4;
	cout << " 人数 :" << Person::_count << endl;
	Student::_count = 0;
	cout << " 人数 :" << Person::_count << endl;
}

int main()
{
	TestPerson();
	return 0;
}

3. 复杂的菱形继承及菱形虚拟继承

3.1 继承分类

单继承

一个子类只有一个直接父类叫做做单继承。

多继承

一个子类有两个即以上的直接父类叫做多继承。

菱形继承

菱形继承是特殊的多继承。

3.2 菱形继承导致的问题

菱形继承可能导致两个问题:

1. 在上面的菱形继承中,假设Person中有一个成员变量_name,那么在Student和Teacher中也会有一个成员变量_name,然而Assistant继承了Student和Teacher,在Assistant中就会有两份_name,会导致数据冗余。 

2. 在访问Assistant中的_name时,由于不知道要访问的到底是哪个_name,是Student还是Teacher呢?就会有二义性的问题。 

class Person
{
public:
	string _name;
};

class Student : public Person
{
protected:
	int _stuid;
};

class Teacher : public Person
{
protected:
	int _teacherid;
};

class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse;
};

void test()
{
	Assistant ast;
	// 这里会有二义性的问题,不知道访问的是哪一个类中的
	ast._name = "a";

	// 指定作用域可以解决二义性的问题,但是无法解决数据冗余的问题
	ast.Teacher::_name = "xxx";
	ast.Student::_name = "yyy";
}

可以用虚拟继承来解决数据冗余的问题,只需要在Student和Teacher的继承Person时使用虚拟继承,加virtual关键字。

class Student : virtual public Person
{
protected:
	int _stuid;
};

class Teacher : virtual public Person
{
protected:
	int _teacherid;
};

 3.3 虚拟继承解决数据冗余的原理

我们可以用内存窗口调试下面这段代码:

class A
{
public:
	int _a;
};
class B : public A
//class B : virtual public A
{
public:
	int _b;
};
class C : public A
//class C : virtual public A
{
public:
	int _c;
};
class D : public B, public C
{
public:
	int _d;
};

int main()
{
	D d;
	d.B::_a = 1;
	d.C::_a = 2;
	d._b = 3;
	d._c = 4;
	d._d = 5;
	return 0;
}

如果不加virtual:

很明显_a有两份

 如果加了virtual:

 那么在B类和C类中,除了存储了继承下来的成员变量,头部存储的是个地址,我们可以看一下:

这个地址存储的含义是这个位置距离共同继承的A的偏移量,虚拟继承之后共同继承的部分就只有一份了,就解决的数据冗余的问题,我们可以用计算器验证以下:

 所以我们可以看出虚拟继承在内存中的存储方式:


4. 继承和组合的区别

1. public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。
2. 合是一种has-a的关系。假设B组合了A,每个B对象中都有一个A对象。
3. 优先使用对象组合,而不是类继承
4. 继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称
为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的
内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很
大的影响。派生类和基类间的依赖关系很强,耦合度高。
5. 对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象
来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复
用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。
组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被
封装。
6. 实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有
些关系就适合继承那就用继承,另外要实现多态,也必须要继承。类之间的关系可以用
继承,可以用组合,就用组合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/564388.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

揭秘链动3+1商业模式:打造未来商业新风潮

大家好&#xff0c;我是微三云周丽&#xff0c;今天给大家分析当下市场比较火爆的商业模式&#xff01; 小编今天跟大伙们分享什么是链动31模式&#xff1f; 在当今商业世界中&#xff0c;随着科技的飞速发展和消费者需求的不断升级&#xff0c;新的商业模式不断涌现。其中&a…

CAPL编程基础

1.程序结构 1.includes{} //头文件 2.variables{} //全局变量声明 3. on preStart{} //初始化 on start{} //工程运行 on preStop{} //工程预停止 on stopMeasurement{} //工程停止 4.int myFunction{} //自定义函数 2.事件 1.键盘事件 on key ‘a’ 2.报…

【漏洞复现】Linksys RE7000无线扩展器 命令注入漏洞(CVE-2024-25852)

0x01 产品简介 Linksys RE7000无线扩展器是一款功能强大、操作便捷的产品,旨在为用户提供无缝的网络覆盖和更快速、更稳定的网络连接体验。 0x02 漏洞概述 Linksys RE7000无线扩展器存在命令注入漏洞,未授权的攻击者可以通过该漏洞执行任意命令,控制服务器。 0x03 测绘语…

《论文阅读》对话推理的对比学习 EMNLP 2023

《论文阅读》对话推理的对比学习 前言名词简介CICERO 数据集方法损失函数实验结果前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手工敲击键盘~ 今天为大家带来的是《Contrastive Learning for Inference in Dialogue》 出版:EMNLP 时…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

8-云原生监控体系-PromQL-函数

Prometheus支持几个函数来操作数据。 文章目录 1. 函数语法解释2. count(v instant-vector)3. topk(n, v instant-vector)4. bottomk(n, v instant-vector)5. increase(v range-vector)6. rate(v range-vector)7. rate 和 increase8. irate(v range-vector)9. predict_linear(…

【Qt常用控件】—— 按钮类控件

目录 1.1 Push Button 1.2 Radio Buttion 1.3 Check Box 1.4 Tool Button 1.5 小结 1.1 Push Button 使⽤ QPushButton 表⽰⼀个按钮. 这也是当前我们最熟悉的⼀个控件了. QPushButton 继承⾃ QAbstractButton . 这个类是⼀个抽象类. 是其他按钮的⽗类. 在 Qt Desi…

项目体检(Health Check)升级上线

在快节奏的现代商业环境中&#xff0c;项目的健康与否直接关系到其最终的成功与否。为了满足这一需求&#xff0c;我们精心打造了项目体检工具&#xff08;Health Check&#xff09;。它不仅仅是一个工具&#xff0c;更是一种对项目健康状况的全面把控和智能诊断。 项目体检工具…

F-logic DataCube3 SQL注入漏洞复现(CVE-2024-31750)

0x01 产品简介 F-logic DataCube3是一款用于光伏发电系统的紧凑型终端测量系统。 0x02 漏洞概述 F-logic DataCube3 /admin/pr_monitor/getting_index_data.php 接口处存在SQL注入漏洞,未经身份验证的攻击者可通过该漏洞获取数据库敏感信息,深入利用可控制整个web服务器。 …

外显子测序wes

外显子是基因组中能够转录组出成熟RNA的部分。一个基因组中所有外显子的集合&#xff0c;即为外显子组。值得注意的是&#xff0c;通常所说的全外显子组测序&#xff0c;是指针对蛋白编码基因的外显子&#xff0c;很少涉及非编码基因。 基因(gene)是DNA中含有特定遗传信息的一…

MapReduce——ReudceTask并行度决定机制

MapReduce——ReudceTask并行度决定机制 1. Reduce任务的数量&#xff08;reduce task count&#xff09;&#xff1a; 这是最基本的决定因素之一。在作业启动时&#xff0c;用户可以指定Reduce任务的数量。更多的Reduce任务意味着更多的并行度&#xff0c;因为每个Reduce任务…

BeautifulSoup模块

【一】Beautifulsoup4初始 【前言】bs4模块 安装pip install beautifulsoup4 【1】什么是beautifulsoup: ​ 是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。(官方) ​ beautifulsoup是一个解析器,…

贪吃蛇的简单实现(c语言)

前言&#xff1a;学完了C语言的基础语法&#xff0c;和一点数据结构的知识&#xff0c;拿贪吃蛇来练练手&#xff0c;并熟悉以前的知识。写完之后&#xff0c;有一种成就感&#xff0c;为以后的学习饱满激情。 注意这里的讲解是由部分到整体的思路。 目录 控制台不能是终端&am…

java可盈保险合同管理系统的设计与实现(springboot+mysql源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的可盈保险合同管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于Spring Boot的…

麒麟服务器操作系统自动化安装应答文件制作

原文链接&#xff1a;麒麟服务器操作系统自动化安装应答文件制作 Hello&#xff0c;大家好啊&#xff01;今天我们将探讨如何为麒麟服务器操作系统制作自动化安装应答文件。在部署大量服务器时&#xff0c;自动化安装是提高效率和确保安装一致性的关键技术。通过使用应答文件&a…

IEC104协议

1. 简介 IEC104规约是一个广泛应用于电力、城市轨道交通等行业的国际标准。 2. 术语解释 遥脉 (电度量)&#xff1a; 是指对现场某装置所发出的脉冲信号进行周期累计的一种远程计数操作。 其实&#xff0c;遥脉也可以看成是被具体规定了采用脉冲计数作为测量方法的一种遥测…

JumpServer搭建堡垒机实战

文章目录 第一步、下载安装第二步、访问异常处理【1】docker方式拉取失败 JumpServer是运维人员可连接内部服务器上进行操作&#xff0c;支持Linux等操作系统的管理工具。 第一步、下载安装 curl -sSL https://resource.fit2cloud.com/jumpserver/jumpserver/releases/latest/…

基于函数计算FC3.0 部署AI数字绘画stable-diffusion自定义模型

基于函数计算FC3.0 部署AI数字绘画stable-diffusion自定义模型 部署AI数字绘画stable-diffusion曲线救国授权github账号 部署ffmpeg-app-v3总结 在讲述了函数计算FC3.0和函数计算FC2.0的操作界面UI改版以及在函数管理、函数执行引擎、自定义域名、函数授权及弹性伸缩规则方面进…

精灵传信系统/支持对接易支付/网站+小程序双端php源码下载

简介 精灵传信支持在线提交发送短信&#xff0c;查看回复短信&#xff0c;在线购买额度&#xff0c;自定义对接易支付&#xff0c;设置违禁词&#xff0c;支持网站小程序双端。&#xff08;文末下载&#xff09; 演示截图 在数字化浪潮的推动下&#xff0c;技术创新正以前所未…

maven安装和配置

1.下载版本选择 如果使用的是idea的话&#xff0c;需要考虑跟maven的适配问题&#xff0c;从博文maven 与 idea版本不适配问题的思考 得出以下结论&#xff1a; 1.idea 2021兼容maven 3.8.1及以前的所有版本。 2.idea 2020兼容maven 3.6.3及以前的所有版本。 4.idea 2019兼容m…