<C++>深度剖析菱形继承

​​在这里插入图片描述

文章目录

  • 什么是菱形继承
  • 探究底层

什么是菱形继承

继承关系形如下图的继承即为菱形继承,或者叫钻石继承。

img
菱形继承的问题:公有继承前提下,如果类A中含有成员变量a,那么类B与类C中都有继承自类A的a,类D中又继承类B与类C,所以类D中这时会有两份a,不仅造成了空间冗余,更造成了访问时的二义性问题。

举个例子,代码如下

struct A
{int a;
};
struct B :public A
{int b;
};
struct C :public A
{int c;
};
struct D :public B, public C
{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,我们不妨打开内存窗口查看d对象

在这里插入图片描述

整个红框就是d对象的对象模型,蓝框就是d对象中继承自类B的部分,绿框就是d对象继承自类C的部分,其中两个紫框就是两份a,这就是造成数据冗余与访问二义性的问题。

解决方法:在类B与类C继承类A时采用虚继承,即在继承方式前加上关键字“virtual”,代码如下

struct A
{int a;
};
struct B : virtual public A
{int b;
};
struct C :virtual public A
{int c;
};
struct D :public B, public C
{int d;
};

这时再去访问类D对象中的a即不会产生二义性问题。


探究底层

为什么数据冗余问题与访问二义性只需要添加一个关键字就可以解决?

我们修改一下代码

struct A
{int a;
};
struct B :virtual public A
{int b;
};
struct C :virtual public A
{int c;
};
struct D :public B, public C
{int d;
};
int main()
{D d;d.a = 1;d.b = 2;d.c = 3;d.d = 4;return 0;
}

刚才我们查看了没有使用虚继承时的d对象在内存中的情况,现在我们来一起看一下使用虚继承后的内存窗口

在这里插入图片描述

我们可以看到,只保留了一份a,已用黄框标注,原来B和C中存储a的地方换成了两个地址,我们在内存窗口中看看这两个地址里面有什么
在这里插入图片描述

B中地址存储了28H,C中地址存储了20H,转换成十进制就是40和32,如果我们把这两个数字分别加上B中存储地址的地址与C中存储地址的地址,就会发现刚好都等于变量a的地址,这就说明在虚继承中,继承自顶端的成员变量会被替换成一个地址,而这个地址指向的空间存储的内容刚好是该地址对于成员变量的偏移量,也就是说只保留了一份a,所以在访问时才不会造成二义性的问题,并且也解决了冗余的问题。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

膜厚测量仪在半导体应用中及其重要

随着科技的不断发展,半导体行业已成为当今世界的核心产业之一。在这个领域中,半导体膜厚测量仪作为关键设备,其精度和可靠性对于产品质量和生产效率具有至关重要的作用。本文将详细介绍半导体膜厚测量仪的工作原理、应用领域以及其在半导体制…

【Unity】使用ScriptableObject存储数据

1.为什么要用ScriptableObject? 在游戏开发中,有大量的配置数据需要存储,这个时候就需要ScriptableObject来存储数据了。 很多人会说我可以用json、xml、txt,excel等等 但是你们有没有想过,假设你使用的是json&#x…

基于YOLOv8深度学习的葡萄病害智能诊断与防治系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

【蓝桥杯-单片机】基础模块LED和按键

文章目录 【蓝桥杯-单片机】Led、按键等基础模块01 前置准备(1)新建工程(4)编写程序 02 基础模块:LED(0)LED原理图(1)对P1整体赋值,控制所有的LED灯&#xff…

Unity Shader实现UI流光效果

效果: shader Shader "UI/Unlit/Flowlight" {Properties{[PerRendererData] _MainTex("Sprite Texture", 2D) "white" {}_Color("Tint", Color) (1, 1, 1, 1)[MaterialToggle] PixelSnap("Pixel snap", float…

【react框架】跟我一起速读Next.js官方入门教学课程文档

文章目录 前言目录结构样式方案正常引入样式文件Tailwind方案CSS Modules方案clsx方案 文字和图片优化文字图片 Pages和Layout的机制PagesLayout 通过Link组件改变路由并且拆分打包提供Hooks通过Vercel创建数据未完待续... 前言 对于那些对Next.js一无所知的前端伙伴来说&…

CNC机加工引入复合机器人可以提高生产效率,降低成本

CNC加工企业在过去依赖大量的人工来完成生产线上的各项任务,包括CNC机床的上下料、物料搬运以及部分装配工作。然而,随着产能需求的不断增长和人工成本的持续上升,企业逐渐意识到自动化升级的重要性与迫切性。 面临的挑战与需求: …

Image Demoireing with Learnable Bandpass Filters

一、简介 标题:Image Demoireing with Learnable Bandpass Filters(https://openaccess.thecvf.com/content_CVPR_2020/papers/Zheng_Image_Demoireing_with_Learnable_Bandpass_Filters_CVPR_2020_paper.pdf) 期刊:CVPR 时间:2020 作者:Bolun Zheng, Shanxin Yuan, …

js【深度解析】代码的执行顺序

代码的分类 我们将每一句要执行的 js 代码当做一个任务,则 js 代码可以按照其执行方式的不同,按下图分类 同步任务:立即执行的代码异步任务:延迟执行的代码 微任务:被放入微任务队列(micro task queue&…

数字化转型导师坚鹏:金融科技咨询方法论

金融科技咨询方法论 ——方法、做法、演法、心法 课程背景: 数字化转型背景下,很多机构存在以下问题: 不知道先进的金融科技咨询方法论? 不知道如何运作金融科技咨询项目? 不知道如何汇报咨询项目关键成果&…

机器学习第29周周报 Beyond Dropout

文章目录 week29 Beyond Dropout摘要Abstract一、泛化理论二、文献阅读1. 题目2. abstract3. 网络架构3.1 特征图失真3.2 失真优化 4. 文献解读4.1 Introduction4.2 创新点4.3 实验过程4.3.1 全连接层实验4.3.2 卷积网络上的实验 4.4 结论 小结参考文献 week29 Beyond Dropout …

练习ROS动作编程

ROS学习记录:动作编程 引言: ​ 通过本实验,我们将联系我们学过的动作编程,客户端发送一个运动目标,模拟小乌龟运动到目标位置的过程,包含服务端和客户端的代码实现,并且带有实时的位置反馈。 希望你在本次学习过后&am…