C++多态学习(二)菱形继承
简介
在前一篇笔记C++多态学习(一)单继承与多重继承中讨论了单继承和多重继承,本文将针对菱形继承进行讨论
菱形继承
class Base{ public: Base() { printf("Base的this指针是:%p!\n", this); } virtual void func() { cout << "Base::func" << endl; } virtual void func1() { cout << "Base::func1" << endl; } virtual void func2() { cout << "Base::func2" << endl; } int b; //4字节 }; class Base1 : public Base { public: Base1() { printf("Base1的this指针是:%p!\n", this); } //虚表指针8字节 void func() override { cout << "Base1::func" << endl; } void func1() override { cout << "Base1::func1" << endl; } virtual void func3() { cout << "Base1::func3" << endl; } int b1; //4字节 }; class Base2 : public Base { public: Base2() { printf("Base2的this指针是:%p!\n", this); } void func() override { cout << "Base2::func" << endl; } void func2() override { cout << "Base2::func2" << endl; } virtual void func4() { cout << "Base2::func4" << endl; } int b2; }; class Derived : public Base1, public Base2 { public: Derived() { printf("Derive的this指针是:%p!\n", this); } void func() override { cout << "Derived::func" << endl; } void func4() override { cout << "Derived::func4" << endl; } void func3() override { cout << "Derived::func3" << endl; } virtual void func5() { cout << "Derived::func5" << endl; } int d; };
内存布局
基类冗余
我们知道Derived
继承自Base1
和Base2
,而Base1
和Base2
又继承自Base
。这意味着Derived
的内存布局中会有两份Base
的拷贝。这会引起数据的不一致性和资源的浪费。
二义性
Derived obj; obj.b = 1; //Derived::b不明确 Base* p = &obj; //基类Base不明确
对于obj.b
,编译器无法确定在通过Dervide
访问Base
的成员b
时应该选择哪条路径。
对于Base* p = &obj
,编译器无法确定p
应该指向通过Derived1
继承的Base
还是通过Derived2
继承的Base
。
小结
本文简单讨论了菱形继承的内存布局以及其可能导致的问题。针对上述问题,可以采用虚继承解决,虚继承将在下一篇笔记中讨论。
参考文章
1.VTable Notes on Multiple Inheritance in GCC C++ Compiler v4.0.1
合集:
C++语法
分类:
C++ / C++语法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架