c++虚继承|菱形继承(也是继承的同名问题)-----virtual修饰的继承方式

本文介绍了C++中的虚继承机制,为了解决菱形继承带来的属性重复问题。通过使用虚继承,确保了类层次中相同属性的单一性,避免了数据冗余。在多继承的场景下,详细阐述了如何通过调用祖先类构造函数来初始化共享属性,并通过一个实例展示了虚继承在菱形继承结构中的应用。
摘要由CSDN通过智能技术生成

虚继承---满足菱形关系才有虚继承

引入虚继承:

  • A类中有一个a属性,A继承产生子类B类有一个属性a,A类再继承产生子类C类也有一个属性a,B、C类继承产生D类 → 普通的继承方式让D类中有两个属性a,最终产生的子类有两个拷贝本,a由谁决定?

解决方案:

  • 让相同的属性只保留一份(两个a只有一个有效)--->(A继承产生B、C类必须要用虚继承,用virtual修饰的继承[类似近亲结婚导致的基因问题])--->这份a必须让A的构造函数初始化(在D类中调用A类(祖先类)的构造函数)

  • 子类中相同的属性a,必须要由它祖父类的构造函数初始化(由A类决定)

  • 菱形继承:必须调用祖父类的构造函数

  • 注意:构造函数的写法

虚继承---virtual修饰的继承方式

class B :virtual public A
{

};

class C :virtual public A           
{

};

用 virtual 修饰的方式,导致a属性只有1个备份,所有a都是一样的 → 在A|B|C|D类中的a的值是一样的,无论用什么访问方式a属性都是一样的,只要是祖父类的属性,在父类中就没有用了

//虚继承 --->菱形继承
class A
{
public:
	A(int a) :a(a) {}
protected:
	int a;
};
class B :virtual public A             //必须要用虚继承
{
public:
	B(int a, int b) :A(a), b(b) {}    //调用A的构造函数
protected:
	int b;
};
class C :virtual public A             //必须要用虚继承
{
public:
	C(int a, int c) :A(a),c(c) {}
	void printC() 
	{
		cout << a << endl;
	}
protected:
	int c;
};
class D :public C, public B          //B和C继承产生D类:采用菱形继承
{
public:
	//多继承中只用调用父类构造函数即可依旧报错:类A不存在默认构造函数
	D() :B(1, 2), C(3, 4) ,A(999)   //,A(999)这里必须调用祖父类的构造函数
	{

	}
	void print() 
	{
        //用virtual继承,a由祖父类的构造函数决定,和父类的构造函数无关
		cout << a << endl;
		cout << B::a << endl;       //只有一个a,没有3个a,所有的a都是同一个值
		cout << C::a << endl;
		printC();                   //间接访问也是一样的
	}  
protected:

};
int main()
{
    D d;
    d.print();
}
/*输出*/

999
999
999
999    B类、C类中的a属性没有继承过来 B:1 C:3
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qiuqiuyaq

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

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

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

打赏作者

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

抵扣说明:

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

余额充值