菱形继承的二义性问题和虚基表

单继承和多继承:
单继承:一个子类只有一个直接父类。
多继承:一个子类有两个或以上的直接父类。
            继承方式:继承多个类时,类之间用逗号分隔。
             子类类名:继承方式(pubilc/protect/private):父类1,继承方式:父类二,......

 

 

 

 菱形继承:在多继承的环境下,两个类的父类相同,并且这两个类被同一个类所继承,此时,便构成了菱形继承。

 

 

 

class A
{
public:
	int a;
};

class B:virtual public A
{
public:
	int b;
};

class C:virtual public A
{
public:
	int b;
	int c;
};

class D :public B, public C
{
public:
	int d;
};

int main()
{
	class D  ret;
	ret.B::a = 2;
	ret.C::a = 3;
	ret.b = 4;
	ret.c = 5;
	ret.d = 6;

如上所示,在编译时会发生错误。

 

如上所示,由于子类D的两个基类中存在同名变量d,所以在访问的时候,编译器并不能确定要访问的到底是哪个变量。就带来了二义性问题。

 

 

解决方法:

在变量名之前加上类名,明确要访问的变量。

 

 

 

菱形继承还会带来数据冗余的问题:

class A
{
public:
	int a;
};

class B:virtual public A
{
public:
	int b;
};

class C:virtual public A
{
public:
	int c;
};

class D :public B, public C
{
public:
	int d;
};

int main()
{
	class D  ret;
	ret.B::a = 2;
	ret.C::a = 3;
	ret.b = 4;
	ret.c = 5;
	ret.d = 6;
}

 

由于B和C都继承自A,所以B和C分别会将A的数据和代码进行一份拷贝。而D又继承了B和C,因此在D中,会存储两份A的数据,造成空间的浪费。

 

 

而虚继承便很好的解决的菱形继承所带来的问题。

虚继承的实现原理:

下面的图就是上面那个简图的扩展:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值