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继承自Base1Base2,而Base1Base2又继承自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

posted @   paw5zx  阅读(54)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示