菱形继承
菱形继承(钻石继承):
两个子类继承同一个父类,又有某个类同时继承上面那两个子类
一、当菱形继承,两个父类拥有相同数据,需要加作用域区分
这里 羊驼继承了两个mAge,要想正确输出必须加作用域加以区分
#include<iostream>
using namespace std;
//动物类
class Animal
{
public:
int mAge;
};
//羊类
class Sheep :public Animal
{
};
//驼类
class Camel :public Animal
{
};
//羊驼类
class SheepCamel :public Sheep, public Camel
{
};
void test01() {
SheepCamel st;
//当菱形继承,两个父类拥有相同数据,需要加作用域区分
//st.mAge = 18;//直接这么写,不加作用域的话是错误的,因为继承了两个mAge,会产生二义性
st.Sheep::mAge = 18;
st.Camel::mAge = 28;
cout << "st.Sheep::mAge= " << st.Sheep::mAge << endl;
cout << "st.Camel::mAge= " << st.Camel::mAge << endl;
}
int main() {
test01();
system("pause");
return 0;
}
利用开发人员命令工具查询之后如下:
D:\vs\vs项目\继承\继承>cl /d1 reportSingleClassLayoutSheepCamel "08 菱形继承.cpp"
用于 x86 的 Microsoft (R) C/C++ 优化编译器 19.29.30138 版
版权所有(C) Microsoft Corporation。保留所有权利。
08 菱形继承.cpp
class SheepCamel size(8):
+---
0 | +--- (base class Sheep)
0 | | +--- (base class Animal)
0 | | | mAge
| | +---
| +---
4 | +--- (base class Camel)
4 | | +--- (base class Animal)
4 | | | mAge
| | +---
| +---
+---
二、虚继承
我们看到,这份数据其实只要有一份就可以,菱形继承导致数据有两份,资源浪费,可以采用虚继承来解决
//动物类
class Animal
{
public:
int mAge;
};
//利用虚继承 解决菱形继承的问题
// 继承之前加上关键字virtual变为虚继承
// Animal类称为虚基类
//羊类
class Sheep :virtual public Animal
{
};
//驼类
class Camel :virtual public Animal
{
};
//羊驼类
class SheepCamel :public Sheep, public Camel
{
};
void test01() {
SheepCamel st;
st.Sheep::mAge = 18;
st.Camel::mAge = 28;
cout << "st.Sheep::mAge= " << st.Sheep::mAge << endl;
cout << "st.Camel::mAge= " << st.Camel::mAge << endl;
cout << "st.mAge= " << st.mAge << endl;//采用虚继承后,可以这么写了
}
输出后发现,只有一份数据,所有数据都是28
利用开发人员命令工具查询之后如下:
D:\vs\vs项目\继承\继承>cl /d1 reportSingleClassLayoutSheepCamel "08 菱形继承.cpp"
用于 x86 的 Microsoft (R) C/C++ 优化编译器 19.29.30138 版
版权所有(C) Microsoft Corporation。保留所有权利。
08 菱形继承.cpp
class SheepCamel size(12):
+---
0 | +--- (base class Sheep)
0 | | {vbptr}
| +---
4 | +--- (base class Camel)
4 | | {vbptr}
| +---
+---
+--- (virtual base Animal)
8 | mAge
+---
SheepCamel::$vbtable@Sheep@:
0 | 0
1 | 8 (SheepCameld(Sheep+0)Animal)
SheepCamel::$vbtable@Camel@:
0 | 0
1 | 4 (SheepCameld(Camel+0)Animal)
vbi: class offset o.vbptr o.vbte fVtorDisp
Animal 8 0 4 0