详解——菱形继承及菱形虚拟继承

news2024/12/29 17:11:37

目录

一,菱形继承

1.1单继承

1.2多继承

1.3菱形继承

1.4菱形继承的问题

1.5虚拟继承解决数据冗余和二义性的原理

二.继承的总结和反思


一,菱形继承

C++三大特性——继承-CSDN博客

1.1单继承

单继承:一个子类只有一个直接父类时称这个继承关系为单继承

1.2多继承

多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承

1.3菱形继承

菱形继承:菱形继承是多继承的一种特殊情况

1.4菱形继承的问题

菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。在Assistant的对象中Person成员会有两份。

class Person
{
public:
	string _name; // 姓名
};
class Student : public Person
{
protected:
	int _num; //学号
};
class Teacher : public Person
{
protected:
	int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};
void Test()
{
	// 这样会有二义性无法明确知道访问的是哪一个
	Assistant a;
	//a._name = "peter";  错误
	// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决
	a.Student::_name = "xxx";
	a.Teacher::_name = "yyy";
}

虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系,在Student和Teacher的继承Person时使用虚拟继承,即可解决问题。需要注意的是,虚拟继承不要在其他地方去使用

class Person
{
public:
	string _name; // 姓名
};
class Student : virtual public Person
{
protected:
	int _num; //学号
};
class Teacher : virtual public Person
{
protected:
	int _id; // 职工编号
};
class Assistant : public Student, public Teacher
{
protected:
	string _majorCourse; // 主修课程
};
void Test()
{
	Assistant a;
	a._name = "peter";
}

1.5虚拟继承解决数据冗余和二义性的原理

为了研究虚拟继承原理,我们给出了一个简化的菱形继承继承体系,再借助内存窗口观察对象成员的模型。

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;
}

下图是菱形继承的内存对象成员模型:这里可以看到数据冗余

下图是菱形虚拟继承的内存对象成员模型:这里可以分析出D对象中将A放到的了对象组成的最下面,这个A同时属于B和C,那么B和C如何去找到公共的A呢?这里是通过了B和C的两个指针,指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A

// 有人可能会有疑问为什么D中B和C部分要去找属于自己的A?那么大家看看当下面的赋值发生时,d是不是
要去找出B/C成员中的A才能赋值过去?
D d;
B b = d;
C c = d;

下面是上面的Person关系菱形虚拟继承的原理解释:

二.继承的总结和反思

1. 很多人说C++语法复杂,其实多继承就是一个体现。有了多继承,就存在菱形继承,有了菱形继承就有菱形虚拟继承,底层实现就很复杂。所以一般不建议设计出多继承,一定不要设计出菱形继承。否则在复杂度及性能上都有问题。


2. 多继承可以认为是C++的缺陷之一,很多后来的语言都没有多继承,如Java

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HarmonyOS】 低代码平台组件拖拽使用技巧之登录组件

【关键字】 HarmonyOS、低代码平台、组件拖拽、登录组件、代码编辑器 1、写在前面 前面我们介绍了低代码中堆叠容器、滚动容器、网格布局、页签容器以及一些常用容器和组件的拖拽使用方法,本篇我们来介绍一个新的组件,这个组件是属于业务组件——登录组…

WPF实战项目十六(客户端):备忘录接口

1、新增IMemoService接口&#xff0c;继承IBaseService接口 public interface IMemoService : IBaseService<MemoDto>{} 2、新增MemoService类&#xff0c;继承BaseService和IMemoService接口 public class MemoService : BaseService<MemoDto>, IMemoService{pub…

毕业设计ASP.NET 1400动漫公司网站【程序源码+文档+调试运行】

摘要 本系统将实现一个动漫公司网站&#xff0c;包括前台用户模块和后台管理员模块。前台用户模块主要包括最新动漫、注册登录、公司简介、公司新闻、动漫中心、联系我们和会员中心等功能。后台管理员模块包括用户管理、公司简介管理、公司新闻管理、动漫类别管理、动漫管理、…

快速上手Banana Pi BPI-M4 Zero 全志科技H618开源硬件开发开发板

Linux[编辑] 准备[编辑] 1. Linux镜像支持SD卡或EMMC启动&#xff0c;并且会优先从SD卡启动。 2. 建议使用A1级卡&#xff0c;至少8GB。 3. 如果您想从 SD 卡启动&#xff0c;请确保可启动 EMMC 已格式化。 4. 如果您想从 EMMC 启动并使用 Sdcard 作为存储&#xff0c;请确…

阿里云服务器ECS产品知识及购买和使用常见问题及答案汇总

本文总结了阿里云用户在购买和使用阿里云服务器中的一些常见的问题&#xff0c;包括什么是云服务器ECS&#xff0c;特性与优势&#xff0c;应用场景&#xff0c;基本概念&#xff0c;使用限制等众多问题&#xff0c;让您全方位了解阿里云服务器&#xff0c;并根据自己的需求选择…

Modbus转Profinet网关:PLC与天信流量计通讯的经典案例

无论您是PLC或工业设备的制造商&#xff0c;还是工业自动化系统的维护人员&#xff0c;可能会遇到需要将不同协议的设备连接组合并通讯的情况&#xff0c;Modbus和Profinet是现代工业自动化中常见的两种通信协议&#xff0c;在工业控制领域中被广泛应用。 在这种情况绝大多数会…

Matlab通信仿真系列——滤波器及其分类

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、滤波器定义 二、滤波…

FastAPI通过SSE进行流式输出

服务端推送 在服务器推送技术中&#xff0c;服务器在消息可用后立即主动向客户端发送消息。其中&#xff0c;有两种类型的服务器推送&#xff1a;SSE和 WebSocket。 SSE&#xff08;Server-Send Events&#xff09; SSE 是一种在基于浏览器的 Web 应用程序中仅从服务器向客户…

解决Android端libc++_shared.so库冲突问题

前言 随着App功能增多&#xff0c;集成的so库也会增多&#xff0c;如果系统中多个so库都使用系统自动生成的libc_shared.so库&#xff0c;如果多个SDK都有该so包&#xff0c;就会出现报错&#xff1a; 解决办法 如果出现该问题&#xff0c;说明您的项目中有多个SDK共同依赖了C标…

《微信小程序开发从入门到实战》学习二十五

3.3 开发创建投票页面 3.3.13 使用页面路径参数 写了很多重复代码&#xff0c;现在想办法将多选和单选投票页面合二为一。 将单选页面改造作为单选多选共同页面。 修改index.js中的代码&#xff0c;将路径都跳转到第一个单选页面&#xff0c;带上单选或多选的标志&#xff…

【搜维尔科技】产品推荐:Virtuose 6D RV,大型工作空间触觉设备

Virtuose 6D RV为一款具有大工作空间并在所有6自由度上提供力反馈的触觉设备&#xff0c;设计专用于虚拟现实环境&#xff0c;特别适合于大型虚拟物体的处理。 Virtuose 6D RV是当今市场上唯一将高工作效率与高工作量相结合在一起的产品。6D RV特别适合于缩放与操纵等应用&…

CentOS 7 使用cJSON 库

什么是JSON JSON是一种轻量级的数据交换格式&#xff0c;可读性强、编写简单。键值对组合编写规则&#xff0c;键名使用双引号包裹&#xff0c;冒号&#xff1a;分隔符后面紧跟着数值&#xff0c;有两种常用的数据类型是对象和数组。 对象&#xff1a;使用花括号{}包裹起来的…

[Android]使用Retrofit进行网络请求

以下是使用 Retrofit 发送 POST 请求获取分页城市列表的 Kotlin 代码示例 1.在你的 build.gradle 文件中添加 Retrofit 和 Gson 的依赖 dependencies {......implementation("com.squareup.retrofit2:retrofit:2.9.0")implementation("com.squareup.retrofit2…

解锁电力安全密码:迅软DSE助您保护机密无忧

电力行业信息化水平不断提高&#xff0c;明显提升了电力企业的生产运营能力&#xff0c;然而随着越来越多重要信息存储在终端计算机中&#xff0c;电力面临的信息安全挑战也越来越多。 作为关键基础设施的基础&#xff0c;电力企业各部门产生的资料文档涵盖着大量机密信息&…

C++数组中重复的数字

3. 数组中重复的数字 题目链接 牛客网 题目描述 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 Input: {2, 3, 1, 0, 2, 5}Output: 2解题…

启发式搜索算法-人工智能

第1关:评估函数和启发信息 第2关:A*搜索算法 class Array2D:"""说明:1.构造方法需要两个参数,即二维数组的 宽和高2.成员变量w和h是二维数组的宽和高3.使用:‘对象[x][y]’可以直接取到相应的值4.数组的默认值都是0"""def __init__(s…

SpringBoot + 通义千问 + 自定义React组件,支持EventStream数据解析!

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 最近ChatGPT非常受欢迎&#xff0c;尤其是…

接口传参数list的时候,items里面放个​​​​​​​list

item里面放个list 先定义一个 list&#xff0c;循环add加入参数

如何用CHAT解释文章含义?

问CHAT&#xff1a;解释“ 本身乐善好施&#xff0c;令名远近共钦&#xff0c;待等二十左右&#xff0c;定有高亲可攀&#xff1b;而且四德俱备&#xff0c;帮夫之缘亦有。主持家事不紊&#xff0c;上下亦无闲言。但四十交进&#xff0c;家内谨防口舌&#xff0c;须安家堂&…

基于C#实现Bitmap算法

在所有具有性能优化的数据结构中&#xff0c;我想大家使用最多的就是 hash 表&#xff0c;是的&#xff0c;在具有定位查找上具有 O(1)的常量时间&#xff0c;多么的简洁优美&#xff0c;但是在特定的场合下&#xff1a; ①&#xff1a;对 10 亿个不重复的整数进行排序。 ②&am…