关于菱形继承那些事

文章介绍了菱形继承的概念,即类Horse和Lv继承Animal,而Luo同时继承两者,当存在相同属性时如何使用virtual关键字解决冲突。通过代码示例展示了未使用virtual导致的多个age属性,以及使用virtual后通过虚基类指针和表格实现单一同一属性的情况。

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

1.什么是菱形继承

        创造一个类,另外另外两个类将其作为父类继承,然后又出现一个类将这两个类作为父类继承,就叫菱形继承。

 Horse和Lv继承Animal的属性,Luo再继承上面两者的属性,这种模型就是菱形继承,那么当Horse和Lv有相同属性而且Luo不能同时继承两个的属性时,Luo的继承方式就要使用到virtual关键字,virtual能够解决菱形继承的问题。

2.代码实现

        当不使用virtual关键字时:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Animal {
public:
	int age;
};
class Horse :public Animal {};
class Lv :public Animal {};
class Luo :public Horse,public Lv {};
int main() {
	Luo l;
	l.Horse::age = 90;
	l.Lv::age = 100;
	cout << l.Horse::age << endl;
	cout << l.Lv::age << endl;
}

 这时候的输出结果是90,100。当然并不符合预期,利用cmd查看一下底层

 明显看到Luo类是有两个age分别是继承两个父类的age属性,为了达到一个age属性的目的,添加virtual关键字:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class Animal {
public:
	int age;
};
class Horse :virtual public Animal {};
class Lv :virtual public Animal {};
class Luo :public Horse,public Lv {};
int main() {
	Luo l;
	l.Horse::age = 90;
	l.Lv::age = 100;
	cout << l.Horse::age << endl;
	cout << l.Lv::age << endl;
}

这时候的输出结果为100,查看底层:

 vbptr(虚基类指针):v:virtual         b:baseb:base        ptr:pointer

vbtable(虚基类表格)

虚基类指针指向的是虚基类表格,此时Luo类只有一个age属性,虚基类表格存储的是偏移量,Horse存储一个8,Lv储存一个4,加上偏移量之后最终都指向Animal的age,所以第一次将其修改为90,第二次修改为100,由于修改的是同一份数据,结果就显示两个相同的age属性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值