C++菱形继承的二义性问题(虚拟继承)

1 篇文章 0 订阅
1 篇文章 0 订阅

C++菱形继承如下:

#include<iostream>
using namespace std;
class A
{
public:
	int a;
};
class B1 : public A
{
public:
	int _B1;
};
class B2 :public A
{
public:
	int _B2;
};
class C :public B1, public B2
{
public:
	int c;
};
int main()
{
	C c1;
	c1.a=5;
	return 0;
}

上面代码是一个简单的菱形继承代码,具有编译错误。

顶层的A公有派生子类B1,B2;

而底层的C类共有继承于B1,B2;

那么就产生于一个问题:

就是创建一个c类对象,通过c类对象访问变量a

编译器不知道是访问B1类的继承下来的B1::a,还是B2::a。

这就是菱形继承的二义性问题。

这个问题可以有两个解法。

第一个也是最不提倡的解法,就是在通过c对象访问a变量时注明是访问哪一个继承对象的变量。

代码如下:

#include<iostream>
using namespace std;
class A
{
public:
	int a;
};
class B1 : public A
{
public:
	int _B1;
};
class B2 :public A
{
public:
	int _B2;
};
class C :public B1, public B2
{
public:
	int c;
};
int main()
{
	C c1;
	c1.B1::a=5;//访问B1中的a变量
	return 0;
}

这种方法浪费了大量的空间,若顶层类的变量很多,则派生出的B1,B2类重复定义A类的变量很多,浪费很大。

以下我推荐第二种方法

即虚拟继承:代码如下

#include<iostream>
using namespace std;
class A
{
public:
	int a;
};
class B1 : virtual public A
{
public:
	int _B1;
};
class B2 : virtual public A
{
public:
	int _B2;
};
class C :public B1, public B2
{
public:
	int c;
};
int main()
{
	C c1;
	c1.a=5;
	return 0;
}

在A派生B1,B2类时,使用虚拟继承,

这样不仅解决了编译器的二义性问题,还会对空间进行节省,

使用虚拟继承为什么会节省空间呢。

因为在使用虚拟继承时,B1和B2在定义时不会按照传统的类模型,而是在后面创建一个空间来储存A类变量,B1和B2中有指针可以找到这个空间,这样就节省了空间。后面A类变量空间是B1和B2共有的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三少爷的剑!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值