虚继承解决菱形继承的原理

菱形继承的问题,是由多重继承的父类祖先是同一个父类导致的。如下面的情况:

菱形继承,会导致同名成员的二义性问题和数据冗余问题,用下面的代码来测试:

class A
{
public:
	int _a;
};
// class B : public A
class B : public A
{
public:
	int _b;
};
// class C : public A
class C : 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;
}

当菱形继承不加处理的话。会导致下面的情况:同名成员的二义性问题

这种二义性问题,用下面的方式即可解决:指定类域

但是还会有下面的数据冗余问题:如下,成员 _a 占据了两份同样大空间(01和02那块内存地址) ,定义成员 d时,分别对 B和C开了一块空间,而B和C又要继承类A,所以B和C都对 _a 这个成员开了一样的空间。

当_a成员不是很大的时候,还好,但当有一群_a这样的同名成员的时候,内存开销就太大了!

虚继承解决了这个问题,它是怎么解决的呢?

用上面的 A,B,C,D类来举例子。当定义出一个D的对象 d 的时候,D中继承了成员 B和 C 的各自的成员变量_b和_c,也通过 B和 C继承了 A 的成员 _a,虚拟继承会将 _a 放在一个公共的区域,通过B和C中指针指向的一张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量可以找到下面的A。

如成员 _b 前面的指针,指向的虚基表里存的 16进制的14,代表 20 个字节,这恰好是_b前面的指针起始位置距离 _a 的距离,知道这个距离后,访问的时候就能找到 _a 的位置了。

再如 _c 前面的指针,指向的虚基表里的 0c ,表示十进制的 12,这个指针的起始位置和 _a 的距离就是 12,访问的时候即可以找到了。

综上所述,在虚拟继承的时候,可以通过两个类里各自指针指向虚基表里的偏移量来计算同名成员的位置,并且内存位置是相同的,这也符合我们的认知。

虽然菱形继承有了虚拟继承来解决问题,但它的底层极其复杂,会对性能造成极大影响!

所以,虽然能解决,但尽量不要设计出菱形继承!!

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

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

相关文章

IP代理科普| 共享IP还是独享IP?两者的区别与优势

通俗地讲,共享IP就像乘坐公共汽车一样,您可以到达目的地,但将与其他乘客共享旅程,座位很可能是没有的。独享IP就像坐出租车一样,您可以更快到达目的地,由于车上只有您一个人,座位是您一个人专用…

我的NPI项目之Android电源系列(四) -- 关于剩余充满时间的问题的代码跟踪-max1720x_battery.c qpnp-smb2.c

从我的NPI项目之Android电源系列(三), 能够看出,healthd是通过读取/sys/class/power_supply/battery/time_to_full_now而进行充满剩余时间的。 在/sys/class/power_supply/battery/...目录下有很多文件,具体内容如下: /sys/class…

一篇了解什么是Token、什么是Jwt

目录 Token什么是TokenToken实现认证流程优缺点 JWT什么是JWTJWT组成JWT加密流程优缺点 Token与JWT的区别常见的加密算法 Token 什么是Token Token: Token是访问资源接口(API)时所需要的资源凭证,也成为令牌 传统的Token 传统的Token&am…

立创EDA与设计技巧

绘制PCB流程: 绘制原理图 ——> PCB布线 ——> 铺铜 器件: 器件就是一个个不同的元件,每个元件不同的引脚有不同的功能,但有可能封装是一样的,所以将器件和封装练习起来,才能将原理图和PCB联系…

Postman创建及删除workspace工作空间

文章目录 一、Postman创建workspace工作空间二、Postman删除workspace工作空间 一、Postman创建workspace工作空间 打开Postman 点击 Workspaces → Create Workspaces 如图所示操作 工作空间创建完成 二、Postman删除workspace工作空间 点击 Workspaces → 选择要删除…

C++ 比 C语言增加的新特性 3 之 命名空间namespace

1. 命名空间 1.1 命名空间 又称为“名字空间”,在内存(全局)中取一块区域并对其进行命名 实际例子: 同一个班级,两个同姓的人,例如:张三和张三,其中一个张三座位是在讲台右边&am…

VTK+QT配置(VS)

先根据vtk配置这个博客配置基本环境 然后把这个dll文件从VTK的designer目录复制到qt的对应目录里 记得这里是debug版本,你也可以配置release都一样的步骤,然后建立一个qt项目,接着配置包含目录,库目录,链接输入&…

Spring之国际化:i18n

学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…

第 377 场周赛虚拟参赛记录及补题

最小数字游戏 3 题目 - 思路 模拟代码 class Solution { public:vector<int> numberGame(vector<int>& nums) {sort(nums.begin(),nums.end());vector<int> ans;for (int i 0;i < nums.size();i ) if (i&1)ans.push_back(nums[i-1]);else ans.…

优维产品最佳实践第20期:控制台全链路监控

之前我们会觉得cmdb自动发现没有上报很难排查&#xff0c;弄不清楚数据的上报链路&#xff1b;监控指标的数据断点很难定位&#xff0c;flink对现场来说是一个黑盒子&#xff1b;apm数据更新不及时到底是上报异常还是入库失败呢&#xff1f; 现在控制台集成了对数据链路的监控…

大模型做实体识别任务的原理

1、背景 命名实体识别&#xff08;named entity recognition&#xff0c;NER&#xff09;&#xff1a;通常是一个序列标注的任务&#xff0c;常见的模型框架有&#xff1a;LSTM-CRF、BERTBILSTMCRF等&#xff0c;该种任务通常被成为flat NER即&#xff1a;每一个token只分配一…

浮点数的转换--IEEE 754

IEEE754标准是一种浮点数表示标准&#xff0c;一般分为 单精度&#xff08;32位的二进制数&#xff09;&#xff1b;双精度&#xff08;64位的二进制数&#xff09; 根据国际标准IEEE754&#xff0c;任意一个二进制浮点数V可以表示为下面形式&#xff1a; V (-1)^s *&#…

Linux---命令行参数+环境变量

一、命令行参数 int main(int argc,char*argv[]) {//...return 0; } 不知道有没有人见过这样的主函数&#xff0c;它带了两个参数&#xff0c;argv接收的参数就叫做命令行参数&#xff0c;因为它的参数是从命令行来的&#xff0c;给大家演示一下&#xff0c;大家就懂了 命令行…

干货//可以翻页的电子画册制作方法

想象一下&#xff0c;你是一位新晋的时尚品牌设计师&#xff0c;想要向全球展示你的设计理念和产品。传统的纸质画册虽然精美&#xff0c;但无法满足现代人对便捷性和互动性的需求。那么&#xff0c;如何解决这个问题呢&#xff1f; 现在&#xff0c;你可以使用翻页电子画册的制…

正则表达式:元字符

一、什么事元字符 正则是由一系列的元字符组成的&#xff0c;所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符&#xff0c;元字符是构成正则表达式的基本元件。 二、元字符的分类 1.特殊单字符 效果&#xff1a; ①.任意字符&#xff08;换行符除外&#xff09;&…

51单片机相关寄存器

前言 单片机复习的时候对应寄存器的记忆感觉很混乱&#xff0c;这里进行一下整理,后面的单词是我用来辅助记忆的&#xff0c;可能并不是表示原本的含义。 P3口的第二功能 0RXD 串行数据输入口 1TXD串行数据输出口2INT0外部中断0输入3INT1外部中断1输入4T0定时器0外部计数输入…

spring之资源操作:Resources

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

等级保护的基本要求(一)

目录 等级保护的标准定位 其他标准的关系 标准适用范围 标准编写思路 描述模型 基于安全保护能力 能力目标 第一级安全保护能力 第二级安全保护能力 第三级安全保护能力 第四级安全保护能力 描述模型-管理要求特点 描述模型-覆盖范围特点 等级保护的标准…

【汇编先导】-- 2

汇编先导 6. 寄存器 存储数据&#xff1a;CPU > 内存 > 硬盘(固态、机械) CPU还可分为&#xff1a; 32位CPU 8 16 32 64位CPU 8 16 32 64(增加了寻址能力) 通用寄存器 # 32位的通用寄存器只有8个 # 可以在任意软件的底层看到 # 通用寄存器可以存储任何值存值的范围…

ES6-11

一、ES6 js的异步和同步&#xff0c;js是单线程语言&#xff1a; 同步&#xff1a;加入主线程&#xff0c;按顺序执行&#xff0c;即上一个同步任务结束后&#xff0c;本任务跟着执行。 异步&#xff1a;加入任务队列&#xff0c;等待主线程上任务都执行完毕&#xff0c;请求主…