菱形继承--菱形虚拟继承

菱形继承--菱形虚拟继承

菱形继承

菱形继承,其继承模型如下:

image.png

菱形继承存在问题,Teacher类和Student类都继承了Person类,所以Teacher类和Student类除了拥有自身的成员变量都还拥有继承于Person的成员变量。

而Assistant类继承了Teacher类和Student类,所以,Assistant类除了拥有自身的数据,还拥有Teacher类和Student类的,再加上Person的。那么问题来了,Assistant类中Person的部分是继承与那个父类的?还是都继承了?

 

看看下面代码:

//菱形虚继承
#include <iostream>
using namespace std;
class A
{
public:
	void fun1()
	{
		cout << "A::fun1" << endl;
	}
protected:
	int _a = 10;
};
class B : public A
{
public:
	void fun1()
	{
		cout << "B::fun1" << endl;
	}
	void fun2()
	{
		cout << "B::fun2" << endl;
	}
protected:
	int _b = 20;
};
class C : public A
{
public:
	void fun1()
	{
		cout << "C::fun1" << endl;
	}
	void fun3()
	{
		cout << "C::fun3" << endl;
	}
protected:
	int _c = 30;
};
class D : public B, public C
{
public:
	void fun1()
	{
		cout << "D::fun1" << endl;
	}
	void fun4()
	{
		cout << "D::fun4" << endl;
	}
protected:
	int _d = 40;
};

int main()
{
	D d;
	system("pause");
	return 0;
}

通过监视窗口观察:

image.png

可以发现,D类除了拥有自身的数据,还拥有B类和C类的,再加上A的。而且A类是B类于C类中都有。那么就很难分清出,当调用D类中A类的那部分时,是从B类还是C类中拿到的。

image.png

可以发现菱形继承存在二义性与数据冗余问题。那么该如何解决呢?

通过虚继承的方式可以成功的解决问题:

#include <iostream>
using namespace std;
class A
{
public:
	void fun1()
	{
		cout << "A::fun1" << endl;
	}
protected:
	int _a = 10;
};
class B : virtual public A
{
public:
	void fun1()
	{
		cout << "B::fun1" << endl;
	}
	void fun2()
	{
		cout << "B::fun2" << endl;
	}
protected:
	int _b = 20;
};
class C : virtual public A
{
public:
	void fun1()
	{
		cout << "C::fun1" << endl;
	}
	void fun3()
	{
		cout << "C::fun3" << endl;
	}
protected:
	int _c = 30;
};
class D : public B, public C
{
public:
	void fun1()
	{
		cout << "D::fun1" << endl;
	}
	void fun4()
	{
		cout << "D::fun4" << endl;
	}
protected:
	int _d = 40;
};

int main()
{
	D d;
	system("pause");
	return 0;
}

分析如下:

image.png

虚继承通过在菱形继承两个父类加上virtual达到虚继承。

image.png

虚继承--解决菱形继承的⼆义性和数据冗余的问题 

  1.  虚继承解决了在菱形继承体系⾥⾯⼦类对象包含多份⽗类对象的数据冗余&浪 费空间的问题。

  2.  虚继承体系看起来好复杂,在实际应⽤我们通常不会定义如此复杂的继承体 系。⼀般不到万不得已都不要定义菱形结构的虚继承体系结构,因为使⽤虚继 承解决数据冗余问题也带来了性能上的损耗。

  3.  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值