news 2026/4/23 14:16:18

《你真的了解C++吗》No.024:菱形继承的解决方案——虚继承的内存布局

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《你真的了解C++吗》No.024:菱形继承的解决方案——虚继承的内存布局

《你真的了解C++吗》No.024:菱形继承的解决方案——虚继承的内存布局

导言:死亡之钻的产生

想象一个经典的继承结构:类B和 类C都继承自类A,而类D同时继承了BC

classA{public:intdata;};classB:publicA{};classC:publicA{};classD:publicB,publicC{};

物理上的灾难
在类D的内存布局中,它会包含两份A的拷贝(一份来自 B,一份来自 C)。当你尝试访问d.data时,编译器会陷入恐慌:你是要 B 里的那个data,还是 C 里的那个?


一、 救星出现:virtual继承

为了解决这种冗余和歧义,C++ 引入了虚继承(Virtual Inheritance)

classB:virtualpublicA{};classC:virtualpublicA{};classD:publicB,publicC{};

A变成了“虚基类”后,无论它在继承链中被提到多少次,在最终的派生类D中,它只会存在一个唯一的实例


二、 物理真相:它是如何实现的?

虚继承的实现比普通继承要复杂得多,因为它打破了 C++ 传统的“连续内存布局”假设。为了共享同一个A,编译器必须引入一套偏移机制。

在大多数编译器(如 GCC 或 MSVC)中,虚继承的实现包含以下核心点:

  1. 虚基类指针(vbptr)
    BC的对象中,编译器会增加一个隐藏的指针。这个指针指向一张虚基类表(vbtbl)
  2. 间接访问
    D内部,访问A的成员不再是通过简单的硬编码偏移量,而是:
  • 先找到vbptr
  • vbtbl中查出A距离当前位置的真实偏移量(Offset)
  • 根据偏移量找到那个唯一的A
  1. 共享基类置底
    D的内存布局中,BC的部分会排在前面,而共享的A被放置在内存的最末尾。

三、 虚继承的昂贵代价

虚继承虽然优雅地解决了歧义,但它并不是免费的午餐:

  • 空间开销:每个对象都需要额外的vbptr
  • 时间开销:每次访问虚基类的成员,都要经历一次额外的指针寻址和偏移计算。这比普通继承要慢。
  • 初始化的责任:在虚继承中,最底层的派生类(D)必须直接调用虚基类(A)的构造函数BCA的构造调用会被编译器自动忽略。这是为了防止A被初始化两次。

四、 架构建议:谨慎动用

在现代 C++ 设计中,我们通常遵循**“组合优于继承”**的原则。如果非要用多重继承,也建议尽量让基类保持为“接口类”(即只有纯虚函数,没有数据成员)。

如果基类没有数据成员,菱形继承带来的“冗余”问题就消失了大部分,你也就不再需要承受虚继承带来的复杂内存模型和性能损耗。


总结:空间的博弈

  • 普通继承:追求速度,内存布局紧凑,但在多重继承下会产生数据冗余。
  • 虚继承:追求逻辑一致性,通过引入vbptr和偏移量确保基类唯一。
  • 虚继承是 C++ 解决复杂对象关系的一种“兜底”机制,它体现了 C++ 在处理复杂多态时的极致灵活性。

下一篇预告:聊完了继承的结构,我们要聊聊继承中的“暗号”。当你在派生类写了一个和基类同名但参数不同的函数时,你以为你在重载,但编译器却在“杀人灭口”。

➡️《你真的了解C++吗》No.025:隐藏(Hiding)而非覆盖(Overriding)的陷阱。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:59:16

DMG‑PEG-Mannoside,DMG-聚乙二醇-甘露糖苷,DMG‑PEG-Man‑PEG-S

DMG‑PEG-Mannoside,DMG-聚乙二醇-甘露糖苷,DMG‑PEG-Man‑PEG-SDMG‑PEG-Mannoside 是一种通过 甘露糖苷(Mannoside, Man) 与 聚乙二醇(PEG) 以及 二硬脂酰甘油(DMG, Dimyristoyl Glycerol&…

作者头像 李华
网站建设 2026/4/23 9:26:50

Trilium Notes联手cpolar,可以打造一个随时随地管理的知识库

Trilium Notes 是一款覆盖多系统的开源笔记工具,核心优势在于支持树状嵌套的笔记组织形式,能把零散的学习资料、工作文档梳理得条理清晰,还具备 Markdown 编辑、全文检索、笔记加密等实用功能,不管是程序员整理代码笔记、学生梳理…

作者头像 李华
网站建设 2026/4/23 9:25:47

微模块机房如何实现智能运维?技术解析来了

在数据中心基础设施向轻量化、边缘化演进的趋势下,微模块机房因其部署快、能效高、占地小等优势,被广泛应用于企业分支、高校、制造车间等场景。然而,很多人仍将其误解为“几个机柜空调”的简单组合。实际上,微模块的核心竞争力在…

作者头像 李华
网站建设 2026/4/23 9:25:50

基于django和python框架的热门车型汽车推荐网站

目录Django与Python框架的汽车推荐网站摘要关于博主开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!Django与Python框架的汽车推荐网站摘要 基于Django和Python框架的汽车推荐网站通过整合用…

作者头像 李华
网站建设 2026/4/23 9:26:13

基于微信小程序的校园外卖平台【源码+文档+调试】

🔥🔥作者: 米罗老师 🔥🔥个人简介:混迹java圈十余年,精通Java、小程序、数据库等。 🔥🔥各类成品Java毕设 。javaweb,ssm,springboot等项目&#…

作者头像 李华