![](https://i-blog.csdnimg.cn/blog_migrate/e7d28d88a08b8c9edacb48a7de5f973f.png)
将上图以菱形继承的方式实现:
创建类:
class Animal
{
public:
int m_age;
};//动物类
class Sheep :public Animal {};//羊类
class Tuo:public Animal{};//驼类
class SheepTuo:public Sheep,public Tuo{};//草泥马类
测试函数:
void test()
{
SheepTuo st;
st.Sheep::m_age = 100;//Sheep::指的是Sheep作用域下的m_age
st.Tuo::m_age = 200;
cout << "Sheep_age = " << st.Sheep::m_age << endl;
cout << "Tuo_age = " << st.Tuo::m_age << endl;
}
int main()
{
test();
system("pause");
return 0;
}
代码运行完发现没有问题:
![](https://i-blog.csdnimg.cn/blog_migrate/527b65f7a8ff55849977225779c38154.png)
但是由于Sheep和Tuo类共同继承了m_age,然后由SheepTuo类再继承,这就导致了SheepTuo的菱形继承产生了两份m_age,造成内存的浪费,而我们知道只需要一份数据即可。
并且发现如果直接打印st.m_age会报错,两份的数据产生了二义性。
具体可以通过命令符查看SheepTuo的对象模型↓,如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/f4d4a89a20dd41ad58e4b3fe6fb8cbba.png)
由此图可知的确有两份m_age.
解决办法:
利用虚继承解决菱形继承的问题,即对代码做一下修改:
class Sheep :public Animal {};//羊类
class Tuo:public Animal{};//驼类
//更改为:
class Sheep :virtual public Animal {};//羊类
class Tuo:virtual public Animal{};//驼类
//继承之前加上关键字 virtual 变为虚继承
//此时Animal类称为 虚基类
运行一下代码:
![](https://i-blog.csdnimg.cn/blog_migrate/217fdb2929f56b4803ed232c04bd2818.png)
底层是如何实现的呢?
回到命令符,此时命令符所显示的SheepTuo模型为(左图):
![](https://i-blog.csdnimg.cn/blog_migrate/a460071f58bcf483b592f42d644e8628.png)
以Sheep为例
![](https://i-blog.csdnimg.cn/blog_migrate/4d71a9e76a94ea020a87356dd639f992.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cccd448509c84ef032f0a3957c221c30.png)
完整代码:
class Animal
{
public:
int m_age;
};
class Sheep :virtual public Animal {};
class Tuo:virtual public Animal{};
class SheepTuo:public Sheep,public Tuo{};
void test()
{
SheepTuo st;
st.Sheep::m_age = 100;
st.Tuo::m_age = 200;
cout << "Sheep_age = " << st.Sheep::m_age << endl;
cout << "Tuo_age = " << st.Tuo::m_age << endl;
}
int main()
{
test();
system("pause");
return 0;
}
//******************
//运行结果均为200
以上为底层的实现逻辑。继承的学习完成,接下来将进入到多态的学习,Up!
2023年2月18日11:50:26