当前位置: 首页 > news >正文

C++的虚基类?

C++ 中的 虚基类(virtual base class) 是为了解决多重继承时的“菱形继承问题(Diamond Problem)”而引入的一种机制。它能确保派生类中只保留一份共享基类的成员,避免重复继承导致的二义性和冗余内存。


🧩 一、菱形继承问题

🎯 场景图:

      A/ \B   C\ /D
  • BC 都继承自 A
  • D 同时继承 BC,间接地继承了 两份 A

🔥 结果问题:

class A {
public:int x;
};class B : public A {};
class C : public A {};
class D : public B, public C {};D obj;
obj.x = 5;  // ❌ 错误!编译器报错:x 不明确(有两个 A::x)

D 有两个 A 子对象:B::AC::A,这就产生了二义性和内存冗余


✅ 二、引入虚基类(virtual)

✔ 解决方法:

class A {
public:int x;
};class B : virtual public A {};  // 虚继承 A
class C : virtual public A {};  // 虚继承 A
class D : public B, public C {};  // OK:只保留一份 A

现在:

D obj;
obj.x = 5;  // ✅ 正常访问 A::x,不再歧义

🧠 三、虚继承的工作原理(底层机制)

  • 编译器会在子类(如 D)中只保留一份虚基类 A
  • 类对象的内存结构中,通过**虚基类指针表(VBPTR)**来访问唯一的基类子对象
  • 需要在运行时通过间接方式访问虚基类,开销略大,但换来的是明确的语义和空间节省

📦 四、虚继承使用语法

class Derived : virtual public Base {};
  • 加在 Base 前,加 virtualpublic/private/protected
  • 必须在所有路径上的继承都声明为 virtual,才有效避免二义性

📊 五、内存结构对比(简化)

类型A 的份数D::x 是否唯一内存大小更大?
普通继承2❌ 不唯一是(重复 A)
虚继承1✅ 唯一稍大(多了虚指针)

🎓 六、虚基类的构造顺序

  • 虚基类始终由最底层派生类负责初始化
  • 构造顺序为:虚基类 → 非虚基类 → 构造自己
class A {
public:A() { std::cout << "A\n"; }
};class B : virtual public A {
public:B() { std::cout << "B\n"; }
};class C : virtual public A {
public:C() { std::cout << "C\n"; }
};class D : public B, public C {
public:D() { std::cout << "D\n"; }
};D d;

输出顺序为:

A
B
C
D

✅ 总结一句话:

虚基类是为了解决多重继承中同一基类被重复继承的问题,它确保派生类只保留一份基类子对象,避免二义性和冗余。


http://www.dtcms.com/a/296817.html

相关文章:

  • 黑马头条项目详解
  • cmake应用:集成gtest进行单元测试
  • MUX同步器
  • 人工智能概念:常用的模型压缩技术(剪枝、量化、知识蒸馏)
  • 一篇文章了解HashMap和ConcurrentHashMap的扩容机制
  • ESP32入门实战:PC远程控制LED灯完整指南
  • pandas库的数据导入导出,缺失值,重复值处理和数据筛选,matplotlib库 简单图绘制
  • AD一张原理图分成多张原理图
  • iview Select的Option边框显示不全(DatePicker也会出现此类问题)
  • rust-参考与借用
  • 爬虫逆向--Day12--DrissionPage案例分析【小某书评价数据某东评价数据】
  • MySQL零基础教程增删改查实战
  • java后端
  • mujoco playground
  • DBA常用数据库查询语句
  • DevOps 完整实现指南:从理论到实践
  • 论文阅读:《Many-Objective Evolutionary Algorithms: A Survey. 》多目标优化问题的优化目标评估的相关内容介绍
  • Android LiveData 全面解析:原理、使用与最佳实践
  • Rust生态中的LLM实践全解析
  • 【C# 找最大值、最小值和平均值及大于个数和值】2022-9-23
  • 项目质量如何提升?
  • 教育培训系统源码如何赋能企业培训学习?功能设计与私有化部署实战
  • 使用 Vue 实现移动端视频录制与自动截图功能
  • MySQL---索引、事务
  • Docker 打包Vue3项目镜像
  • 互联网广告中的Header Bidding与瀑布流的解析与比较
  • 性能测试-groovy语言1
  • 使用 LLaMA 3 8B 微调一个 Reward Model:从入门到实践
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-19,(知识点:PCB布局布线的设计要点)
  • 类和包的可见性