首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

菱形继承问题及解决方法—虚继承与虚基类(C+)

菱形继承

菱形继承的概念

两个派生类继承同一个基类,又有某个类同时继承着这两个派生类

菱形继承典型案例

这种继承带来的问题主要有两方面:

羊和驼都继承了动物的类成员,当羊驼想要使用时,会产生二义性

羊驼实际继承了两份来自动物的数据,但实际只需要一份

想要解决有两个思路,一是给羊驼的每一份数据加上作用域,但本质上羊驼还是继承了两份数据。二是通过虚继承的方式,使羊驼仅继承一份数据。

示例代码

#include

using namespace std;

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 = 18;

st.Tuo::m_Age = 28;

cout

cout

}

int main()

{

test();

system("pause");

}

代码运行结果如下:

可以看到羊驼实际上存在两份数据,为了更直观的看到羊驼类的对象模型,可以借助VS自带的命令提示工具,到cpp文件存放目录后执行,其中就是文件名,执行结果如下:

很明显羊驼从羊和驼两个父类中各自继承了一份,通过限定作用域的方式无法彻底解决这个问题,这个时候就要使用虚继承

虚继承与虚基类

具体实现为在羊类和驼类的继承前加上virtual关键词,Animal类称为虚基类 代码如下:

#include

using namespace std;

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 = 18;

st.Tuo::m_Age = 28;

cout

cout

cout

}

int main()

{

test();

system("pause");

}

此时的运行结果为:

可以看到此时可直接用访问类成员,说明此时羊驼类中的只有一份

再次借助VS命令提示工具查看对象模型,运行结果如下:

画的有点凌乱......

可以看出羊类和驼类中的数据只是一个虚基类指针,并未继承具体的数据,这个虚基类指针指向各自的虚基类表,而虚基类表中存在一个偏移量,通过这个偏移量再加上首地址可以找到基类中的数据,所以实际上羊驼只继承了一份数据(也就是基类中的那份)。

摘自https://cloud.tencent.com/developer/article/2141820

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230405A06MRS00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券