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

  • 16
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值