C++——类的虚继承

某些需求抽象成类图后,可能会出现这样的情况:类A作为类B和类C的父类并且类B和类C同时作为类D的父类。

将上方类图进行完善后,可以得到如下类图。

 根据所画的类图,可以编译出如下代码,然后定义一个Delta类的对象,名叫alpha。为了简化操作,各个类中的成员变量和成员函数均设置为public权限。然后我们进行一次简单的Delta类对象alpha的数值输出。

根据上述代码,可以看到,alpha的alpha值并没有成功输出并在开始编译后报错,其原因是Beta类和Charlie类在继承了Alpha类的成员变量后Beta和Charlie中都有Alpha的成员变量,导致编译器无法识别处所输出的数值为Beta的alpha还是Charlie的alpha。

因此,如果想要输出预想的数值,应该在“alpha.”后加上“类名::”表示是哪个类的alpha,更改后的代码以及结果如下,这里以Beta类的alpha为例。

#include<iostream>
using namespace std;
class Alpha
{
public:
	int alpha;
	Alpha()
	{
		alpha = 1;
	}
};
class Beta :public Alpha
{
public:
	int beta;
	Beta()
	{
		beta = 2;
	}
};
class Charlie :public Alpha
{
public:
	int charlie;
	Charlie()
	{
		charlie = 3;
	}
};
class Delta :public Charlie, public Beta
{
public:
	int delta;
	Delta()
	{
		delta = 4;
	}
};
int main()
{
	Delta alpha;
	cout<<alpha.Beta::alpha<<endl;
	return 0;
}

 

但是问题并没有彻底解决。

int main()
{
	Delta alpha;
	cout<<alpha.Beta::alpha<<endl;

	cout << sizeof(alpha) << endl;
	return 0;
}

如果将主函数中的代码加上一句,就可以看到Delta类的alpha对象所占用的空间。通过计算我们可以算出,预想的sizeof(alpha)的值应该为16,这个值可以通过四个int类型变量占用的空间数算出。  

如果Beta和Charlie类继承Alpha的成员变量所占内存较大,则会大大增加代码冗余度。假设将Alpha类的成员变量替换成一个容量为100的数组,最后得到的Delta类的alpha的大小如下,这显然不符合实际需求。

所以,针对这种现象,C++中的解决方法就是将继承了Alpha类的Beta类和Charlie类设置成【虚继承】,这种方式是一种解决菱形继承数据冗余的常用方法。

#include<iostream>
using namespace std;
class Alpha
{
public:
	int alpha;
	Alpha()
	{
		alpha = 1;
	}
};
class Beta:virtual public Alpha
{
public:
	int beta;
	Beta()
	{
		beta = 2;
	}
};
class Charlie:virtual public Alpha
{
public:
	int charlie;
	Charlie()
	{
		charlie = 3;
	}
};
class Delta :public Charlie,public Beta
{
public:
	int delta;
	Delta()
	{
		delta = 4;
	}
};
int main()
{
	Delta alpha;
	cout << alpha.alpha << endl;
	cout << sizeof(alpha) << endl;
	return 0;
}

//虚继承:解决菱形继承的数据冗余

通过这种方式更改的代码输出的结果如下。

虽然在Alpha类的成员变量为alpha时,alpha占用的空间确实比非虚继承的alpha占用的空间多,但如果alpha作为一个大容量的成员变量,这种方法的优势就能显现出来。

虚继承的sizeof(alpha)所占空间大小

 

虚继承的sizeof(alpha)所占空间大小 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值