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

简介: 虚继承解决菱形继承的原理

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

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

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,访问的时候即可以找到了。

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

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

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

相关文章
|
定位技术
百度地图缩放级别与比例尺的关系
百度地图缩放级别与比例尺的关系
2195 0
|
JavaScript 测试技术 数据库
基于 SpringBoot+Vue 的在线考试系统的研究与实现(附源码,教程)
基于 SpringBoot+Vue 的在线考试系统的研究与实现(附源码,教程)
|
缓存 图形学
游戏通用解决方案之红点设计
游戏通用解决方案之红点设计
1521 0
|
12月前
|
人工智能 边缘计算 运维
AI守护隐私?边缘计算设备的“护城河”原来可以这么建
AI守护隐私?边缘计算设备的“护城河”原来可以这么建
518 0
|
人工智能 NoSQL 数据可视化
n8n:16万Star超明星项目的架构解读
n8n从单体架构逐步演进为企业级集成平台,具备AI集成能力,适用于自动化场景,成为iPaaS领域的优选方案。
854 0
n8n:16万Star超明星项目的架构解读
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
6139 56
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
存储 虚拟化 iOS开发
VMware ESXi 7.0U3v macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版
VMware ESXi 7.0U3v macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版
578 0
VMware ESXi 7.0U3v macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版
|
内存技术
关于 Qwen-Omni 模型的音频输出格式转换
Qwen-Omni 官方文档声称音频输出为 WAV 格式,但实际上为 PCM 格式。通过将每个 chunk 的 base64 编码音频数据解码并拼接,可生成 24kHz、16位、单声道的 PCM 文件。使用 FFMPEG 可将其转换为其他格式,如 MP3。示例代码展示了如何解码并转换音频文件。
|
人工智能 机器人 API
AppFlow:将文心智能体加入你的社交群聊
通过阿里云AppFlow,只需简单配置,无需编写代码,即可将百度文心智能体接入钉钉群聊,为群聊添加一个专业的AI助手。本文以钉钉群聊为例,详细介绍了如何创建钉钉应用、AI卡片、配置AppFlow连接流以及创建钉钉机器人,最终实现AI助手在群聊中的应用。
1227 9
|
Java Maven Spring
SpringBoot项目创建失败或无法启动,启动报错时的常见问题及解决方案
文章列举了在IDEA中创建Spring Boot项目时可能遇到的常见问题及其解决方案,如项目不被识别为Maven项目、依赖未找到或报红、JDK版本不一致和POM文件中的Jar包下载失败等问题。
6883 0
SpringBoot项目创建失败或无法启动,启动报错时的常见问题及解决方案

热门文章

最新文章