虚继承 -- 解决菱形继承问题以及无法跨继承访问

本文介绍了菱形继承的概念,其导致的二义性问题,以及如何通过使用虚继承来解决。讲解了如何在代码中应用虚继承,以及注意事项,如多继承的区别和限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

什么是菱形继承?

菱形继承造成的问题: 

如何解决这种问题:  

代码分析: 

注意:  

什么是菱形继承?

上图就是一个菱形继承的例子。 

菱形继承:    有两个类(Father,Mother),都继承于一个类(Human),然后还有一个类,又同时继承于这两个类(Son),这样就构成了菱形继承。

菱形继承造成的问题: 

1.  会导致继承于Human类中的属性形成二义性,因为Father类从Human中继承了name和age,Mother类也从Human中继承了name和age,子类Son同时继承了父类和母类的name和age。所以在子类中直接访问name和age,编译器就不知道访问的是哪个类继承来的name和age(二义性

访问就会报错 ->  属性不明确。 

如何解决这种问题:  

菱形继承中,必然会存在不明确的属性,和多继承中有所不同(因为多继承中有时可以避免)。为了能够方便写代码(直接访问name和age),我们可以使用虚继承来解决。  

class Human {
public:
	Human();
	Human(const string& name, int age);
protected:
	string name;
	int age;
};

class Father : virtual public Human {
public:
	Father();
	Father(const string& name, int age);
};

class Mother : virtual public Human {
public:
	Mother();
	Mother(const string& name, int age);
};

class Son : public Father, public Mother {
public: 
	Son(const string& name, int age);
};

int main(void) {

	system("pause");

	return 0;
}

Human::Human()
{
}

Human::Human(const string& name, int age)
{
	this->name = name;
	this->age = age;
}

Father::Father()
{
}

Father::Father(const string& name, int age):Human(name,age)
{
}

Mother::Mother()
{
}

Mother::Mother(const string& name, int age):Human(name,age)
{
}

Son::Son(const string& name, int age)
{
	this->name = name;
	this->age = age;
}

代码分析: 

1.  我们在Father和Mother类继承前加上了virtual关键字,这样在Son的构造函数中就可以直接访问name和age了,因为虚继承之后,编译器认为name和age既不来自于Father,也不来自于Mother,而是直接访问的Human类中的,这样就不会有二义性了。

2.   那么共同的祖先就被称为虚基类(此处的Human)

3.  实现虚继承后,我们在初始化继承来的name和age属性的时候,也可以直接调用Human的构造函数。 

 这样也是可以的。 

注意: 

1.  虽然多继承中也有可能存在二义性,但是是不能使用虚继承来解决的。(仔细对比就知道,菱形继承存在三层继承关系,多继承一般就两层) 

2.  只有在实现虚继承的时候,子类才能调用父类的父类的(也就是Son调用Human)类中的属性和方法,其它情况,子类最多只能访问父类的。  (父类的父类等等,是不能访问的) 

 Huamn类中的test()方法,在没有实现虚继承的情况下,也会报错->不明确,因为这个方法,Father类和Mother类中也继承了。

不使用虚继承,直接使用Human类的构造方法,也是会报错的。 

3.  所以,多层继承中,子类最多只能访问到上一层。(在没有实现虚继承的情况下) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值