菱形继承
菱形继承概念:
两个派生类(子类)继承同一个基类(父类)
又有某个类同时继承这两个派生类
这种继承被称为菱形继承,或者钻石继承
动物
羊 驼
草泥马(羊驼)
菱形继承问题:
1)羊继承了动物的数据,驼同样继承了动物的数据,当草泥马使用数据时,就会产生二义性
2)草泥马继承自动物的数据继承了两份,其实我们清楚,这份数据我们只需要一份就可以了 比如:羊有一个属性m_Age = 5;驼有一个属性m_Age = 6;
那么羊驼继承两者后,就会产生二义性
现在访问继承过来的m_Age,这个属性是5呢还是6呢?
代码示例:
void test01()
{
YangTuo yt1;
yt1.Yang::m_Age = 5;
yt1.Tuo::m_Age = 6;
cout << "yt1.Yang::m_Age =" << yt1.Yang::m_Age << endl;
cout << "yt1.Tuo::m_Age =" << yt1.Tuo::m_Age << endl;
//cout << yt1.m_Age << endl; //会报错 未初始化局部变量"yt1"
}
解决方法:利用虚继承 解决菱形继承问题(virtual关键字)
虚继承之后,就只有一个m_Age了,最后给m_Age赋值多少,他就是多少 虚继承的本质:
继承过来的是一个vbptr的东西
这是一个虚基类指针链表,里面存放的是m_Age的地址,以及不同m_Age的偏移量
示例代码:
void test01()
{
YangTuo yt1;
yt1.Yang::m_Age = 5;
yt1.Tuo::m_Age = 6;
cout << "yt1.Yang::m_Age =" << yt1.Yang::m_Age << endl;
cout << "yt1.Tuo::m_Age =" << yt1.Tuo::m_Age << endl;
cout << yt1.m_Age << endl; //不报错,最后输出为6
}
全部代码:
#include <iostream>
using namespace std;
class dongWu {
public:
int m_Age;
};
//羊类
class Yang : virtual public dongWu {};
//驼类
class Tuo : virtual public dongWu{};
//羊驼类
class YangTuo : public Yang, public Tuo {};
void test01()
{
YangTuo yt1;
yt1.Yang::m_Age = 5;
yt1.Tuo::m_Age = 6;
cout << "yt1.Yang::m_Age =" << yt1.Yang::m_Age << endl;
cout << "yt1.Tuo::m_Age =" << yt1.Tuo::m_Age << endl;
cout << yt1.m_Age << endl; //不报错,最后输出为6
}
int main()
{
test01();
system("pause");
return 0;
}