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

菱形继承

菱形继承的概念

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

菱形继承典型案例

file

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

  • 羊和驼都继承了动物的类成员,当羊驼想要使用时,会产生二义性
  • 羊驼实际继承了两份来自动物的数据,但实际只需要一份

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

示例代码

#include<iostream>
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 << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
    cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
}
int main()
{
    test();
    system("pause");
}

代码运行结果如下:

file

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

file

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

虚继承与虚基类

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

#include<iostream>
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 << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
    cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;

    cout << "m_Age=" << st.m_Age << endl;
}
int main()
{
    test();
    system("pause");
}

此时的运行结果为:

file

可以看到此时可直接用st.m_Age访问类成员,说明此时羊驼类中的m_Age只有一份
再次借助VS命令提示工具查看对象模型,运行结果如下:
file

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


写的有点乱,如果看不懂的话可以移步[黑马程序员]的视频讲解,讲的相当详细,点此跳转

本文作者:小小黑
本文链接:https://lonelyenderman.top/archives/723
版权声明:本站采用 BY-NC-SA 进行许可。转载请注明出处!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(*^▽^*)
 ̄﹃ ̄
(╯‵□′)╯︵┴─┴
(~ ̄▽ ̄)~
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
( ͡° ͜ʖ ͡°)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
つ﹏⊂
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
(´▽`ʃ♡ƪ)
w(゚Д゚)w
(๑•̀ㅂ•́)و✧
(#`O′)
凸(艹皿艹 )
o(≧口≦)o
≡ω≡
(*/ω\*)
○| ̄|_
(⊙ˍ⊙)
Σ(っ °Д °;)っ
o( ̄ヘ ̄o#)
<( ̄︶ ̄)>
(。・∀・)ノ゙
(o゜▽゜)o☆
╥﹏╥
ヾ(´・ω・`)ノ
😂
😀
😅
😊
🙂
😍
😘
😜
😝
😏
😒
🙄
😳
😔
😫
😱
😭
😶
🌚
😣
🤨
😣
🤐
😪
🤤
🥵
🤮
😨
😱
😓
🤬
👴
🤡
🙈
💊
🙏
🤺
💩
👻
🙌
🖕
👍
👫
👌
🙏
👀
🐒
🔪
Source: github.com/zhheo/Sticker-Heo
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
Heo
花!
上一篇
下一篇