菱形继承和虚基表

本文深入探讨了C++中的菱形继承问题,解释了菱形继承导致的二义性和冗余,并通过实例展示了如何使用虚基类来解决这些问题,确保派生类中只保留一份间接基类的成员。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

菱形继承和虚基表

1 菱形继承

在这里插入图片描述
 从图中,我们知道派生类D继承B,C,所以D中存在B,C的所有数据,而由于B,C也都继承A,所以D中有两份A的数据,m_a,所以D无法直接访问A中的数据,必须加限定作用域指明是来自于哪个基类B,C中的m_a。

class Base
{
public:
 int m_base;
};
class A : public Base
{
public:
 int m_a;
};
class B :public Base
{
public:
 int m_b;
};
class D : public A, public B
{
public:
 int m_d;
};
void main()
{
 D d;
 d.m_d = 0;
 //d.m_a = 1; 不能访问
 d.m_b = 2;
 d.m_base=3;
 //d.A::m_base = 3;//要访问只有加限定作用域
 //d.B::m_base = 4;
}

2 解决办法

在这里插入图片描述

 而如果A,B是虚拟继承(使得在派生类中只保留一份间接基类的成员。),则能防止B中有两份base的数据。如果是虚拟继承,则只有一份base的数据,存在D中,而A,B则存放虚基表(里面存放对base的偏移量)
代码

class Base
{
public:
 int m_base;
};
class A : virtual public Base
{
public:
 int m_a;
};
class B :virtual public Base
{
public:
 int m_b;
};
class D : public A, public B
{
public:
 int m_d;
};
void main()
{
 D d;
 d.m_d = 0;
 d.m_a = 1;
 d.m_b = 2;
 d.m_base=3;
 //d.A::m_base = 3;//如果是非虚拟继承,加限定作用域
 //d.B::m_base = 4;
}

虚拟继承,对于D的两个基类,A,B各自产生一份虚基表
在这里插入图片描述

输入虚基表的地址
在这里插入图片描述
偏移量为14 00 00 00 即为20,在内存一上A开始向后20位,为m_base的位置
如果不是虚拟继承
在这里插入图片描述
同上,可以看出A存放的m_base=3,B的m_base=4,造成二义性和冗余

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值