C++菱形继承的实现

将上图以菱形继承的方式实现:

创建类:

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;
}

代码运行完发现没有问题:

但是由于Sheep和Tuo类共同继承了m_age,然后由SheepTuo类再继承,这就导致了SheepTuo的菱形继承产生了两份m_age,造成内存的浪费,而我们知道只需要一份数据即可。

并且发现如果直接打印st.m_age会报错,两份的数据产生了二义性。

具体可以通过命令符查看SheepTuo的对象模型↓,如下所示:

由此图可知的确有两份m_age.

解决办法:

利用虚继承解决菱形继承的问题,即对代码做一下修改:

class Sheep :public Animal {};//羊类
class Tuo:public Animal{};//驼类
//更改为:
class Sheep :virtual public Animal {};//羊类
class Tuo:virtual public Animal{};//驼类
//继承之前加上关键字 virtual 变为虚继承
//此时Animal类称为 虚基类

运行一下代码:

底层是如何实现的呢?

回到命令符,此时命令符所显示的SheepTuo模型为(左图):

以Sheep为例

完整代码:

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
菱形继承的优点: 1. 代码重用:菱形继承允许子类同时继承两个不同的父类,从而可以重用这两个父类中的成员和方法,减少了代码的重复编写。 2. 灵活性:菱形继承可以实现多继承的一种方式,使得子类可以同时具有多个父类的特性和功能,增加了灵活性和扩展性。 3. 层次清晰:菱形继承的结构相对清晰,可以更好地表示对象之间的关系和继承层次。 菱形继承的缺点: 1. 冗余数据:由于派生类同时继承两个父类,而这两个父类又都继承自同一个基类,导致派生类中可能存在相同的成员变量和方法,造成了数据的冗余。 2. 二义性:菱形继承可能引发成员函数的二义性问题。如果两个父类中存在相同的成员函数,而派生类又没有明确指定使用哪个父类的成员函数,会导致编译器无法确定调用哪个函数。 3. 破坏封装性:菱形继承可能破坏基类的封装性。如果两个父类都访问了基类的私有成员,而派生类又同时继承了这两个父类,就会导致派生类可以直接访问基类的私有成员,违背了封装的原则。 为了解决菱形继承带来的冗余数据和二义性问题,C++ 提供了虚继承(virtual inheritance)的机制。通过在派生类对基类的继承声明中使用 `virtual` 关键字,可以避免数据冗余和二义性的问题。虚继承将共同基类的成员在派生类中只保留一份,解决了数据冗余的问题;而对于二义性问题,则需要在派生类中明确指定调用哪个父类的成员函数。 综上所述,菱形继承在代码重用和灵活性方面具有优点,但也存在冗余数据、二义性和破坏封装性的缺点。在使用菱形继承时,需要注意这些问题,并根据具体情况选择使用虚继承或其他方式来解决。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值