最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解C++中菱形繼承的原理與解決方法

 更新時間:2023年02月01日 11:44:26   作者:謎一樣的男人1  
C++中的菱形繼承是多繼承的一種特殊情況,本文將通過海里帶大家了解一下菱形繼承形成的原因以及想應的解決方法,感興趣的可以了解一下

菱形繼承形成原因

多繼承,呈菱形狀

菱形繼承代碼:

class A 
{
public:
    A() {}
    int _a ;
};
class B :public A 
{
public:
    //會存在父的int a;
    B() {}
    int _b ;
};
class C :public A 
{
public:
   //會存在父的int a;
    C() {}
    int _c ;
};
class D :public B,public C 
   
{
public:
   //會存在父的int a;    問題來了這個a是  父親b中的a 還是 父親c中的a -- 二義性;
    
   //父的int b;
   //父的int c;
    D() {}
    int _d ;
};
int main()
{
    
   
    D d;
    d.B::_a = 1;
    d.C::_a = 2;
    d._b = 3;
    d._c = 4;
    b._d = 5;
    cout << d._a << endl;//報錯  提示b.a具有二義性
    return 0;

}

出現(xiàn)二義性變量的內(nèi)存布局

可以看到上圖中紫色框兩部分,是出現(xiàn)二義性的兩份A::_a變量,編譯器無法自主確定需要用哪一個,可以d::A_a 或者 d::B_a這樣使用;

應對方案

虛繼承 vitrual

vitrual修飾使派生類出現(xiàn)二義性的父類繼承部分(菱形的腰部)

class A 
{
public:
    A() {}
    int _a ;
};
class B :virtual public A //virtual修飾
{
public:
    //父的int a;
    B() {}
    int _b;
};
class C :virtual public A  //virtual修飾
{
public:
   //父的int a;
    C() {}
    int _c ;
};
class D :public B,public C 
   
{
public:

    //自己的 int a;(二義性的父親繼承經(jīng)virtual修飾)
   //父的int b;
   //父的int c;
    D() {}
    int _d;
};
int main()
{
    
    D d;
    d.B::_a = 1;
    d.C::_a = 2;
    d._b = 3;
    d._c = 4;
    b._d = 5;
    cout << d._a << endl;//沒問題,輸出2,這個2是D類成員通過繼承,使得d自己獨有且只有一份的 A::_a成員變量;
    return 0;
}

解決二義性變量內(nèi)存布局–虛基表

可以看到原先存放兩個二義性數(shù)據(jù)A::a和B::a的位置,變成了一個地址?

這個兩個地址就叫虛基表指針

通過對虛基表的進一步內(nèi)存研究,發(fā)現(xiàn)了虛基表緊著得下一個位置存放了一個偏移量,這個偏移量是存放該虛基表指針的內(nèi)存位置,與當前派生類獨有一份的成員變量_a之間的偏移長度;

這樣我們直接使用d::a的時候,因為獨有一份,也不會出現(xiàn)數(shù)據(jù)二義性的問題了;

注意,這和多態(tài)中的虛表(虛函數(shù)表兩回事)

其次,虛基表的指針,經(jīng)過測試,也是某個多繼承派生類的多對象共用的;

eg: D d1,d2; 其中d1,d2兩個對象 上圖的這兩張?zhí)摶碇羔樖且粯拥模蚝芎唵?,D類類型都一樣,那么某個位置起,到另一個相對位置偏移量肯定是固定的!

(同類型的虛表指針也如此,復用節(jié)省空間嘛)

感悟

繼承,多態(tài)無疑為我們創(chuàng)造了很多的價值,但是像菱形繼承這種弊端也是存在的,本質(zhì)是多繼承而引起的問題,在一些語言中禁止了多繼承的行為,總之有利有弊,雖然C++允許了多繼承,但還是盡量別寫多繼承這種模式,復雜度和出現(xiàn)問題的概率都很大;

關(guān)于代碼復用等的另一種關(guān)系-組合

繼承是每個派生類都能相對于繼承is-a的關(guān)系; 每個派生類對象都是一個基類對象; 耦合度高

// Car和BMW Car和Benz構(gòu)成is-a的關(guān)系
class Car{
    protected:
    string _colour ="白色"; // 顏色
    
    string _num ="陜ABITB";// 車牌號
};

class BMW:public Car{
    public:
    void Drive() {cout <<"好開-操控"<< end1;}
    };
    
    class Benz : public Car{
        public:
        void Drive() {cout <<"好坐-舒適"<< endl;}
        };

優(yōu)先考慮組合has-a的關(guān)系; eg: 汽車-輪胎,has-a,組合(class 輪胎 作為class 車的成員嵌套) 耦合度低

// Tire和Car構(gòu)成has-a的關(guān)系

class Tiref{
    protected:
    string _brand = "Michelin";// 品牌
    size_t size = 17;// 尺寸
    
};
class Car{
    protected:
    string _colour ="白色";// 顏色
    string _num ="陜ABITO";// 車牌號
    Tire _t;// 輪胎

};

到此這篇關(guān)于詳解C++中菱形繼承的原理與解決方法的文章就介紹到這了,更多相關(guān)C++菱形繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C/C++字節(jié)序的深入理解

    C/C++字節(jié)序的深入理解

    本文主要介紹了C/C++字節(jié)序的深入理解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • 淺析VC++中的頭文件包含問題

    淺析VC++中的頭文件包含問題

    類中盡量采用指針或引用方式調(diào)用其它類,這樣就可以只聲明class xxx了。并且這也符合資源最優(yōu)利用,更利于使用多態(tài)
    2013-09-09
  • 講解C++中的枚舉類型以及聲明新類型的方法

    講解C++中的枚舉類型以及聲明新類型的方法

    這篇文章主要介紹了講解C++中的枚舉類型以及聲明新類型的方法,是C預言入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C語言的隨機數(shù)rand()函數(shù)詳解

    C語言的隨機數(shù)rand()函數(shù)詳解

    這篇文章主要為大家詳細介紹了C語言的隨機數(shù)rand()函數(shù),使用數(shù)據(jù)庫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C++模板的特化超詳細精講

    C++模板的特化超詳細精講

    最近我學習了C++中的模板相關(guān)知識,模板是泛型編程的基礎(chǔ),十分重要。所以特意整理出來一篇文章供我們一起復習和學習
    2022-08-08
  • C與匯編混合編程的實現(xiàn)示例

    C與匯編混合編程的實現(xiàn)示例

    本文主要介紹了C與匯編混合編程的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • C++實現(xiàn)聊天小程序

    C++實現(xiàn)聊天小程序

    這篇文章主要為大家詳細介紹了C++實現(xiàn)聊天小程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言獲取Linux系統(tǒng)精確時間的方法

    C語言獲取Linux系統(tǒng)精確時間的方法

    下面小編就為大家?guī)硪黄狢語言獲取Linux系統(tǒng)精確時間的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • C語言中break與continue的用法和區(qū)別詳解

    C語言中break與continue的用法和區(qū)別詳解

    當我們使用while或for循環(huán)時,如果想提前結(jié)束循環(huán)(在不滿足結(jié)束條件的情況下結(jié)束循環(huán)),可以使用break或continue關(guān)鍵字,這篇文章主要給大家介紹了關(guān)于C語言中break與continue的用法和區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • C++ sdl實現(xiàn)渲染旋轉(zhuǎn)視頻的方法分享

    C++ sdl實現(xiàn)渲染旋轉(zhuǎn)視頻的方法分享

    一般情況下播放視頻時不需要旋轉(zhuǎn),但是如果是移動端錄制的視頻有時會出現(xiàn)rotate參數(shù),且視頻寬高也是互換的。所以本文為大家準備了利用sdl實現(xiàn)渲染旋轉(zhuǎn)視頻的方法,需要的可以參考一下
    2022-12-12

最新評論

濮阳市| 沧州市| 嘉善县| 吉林市| 洪江市| 云浮市| 恩平市| 芦溪县| 清原| 尼勒克县| 无为县| 满洲里市| 高雄县| 梁山县| 瓦房店市| 乌鲁木齐县| 广东省| 宣威市| 金平| 武穴市| 鄂托克旗| 乐业县| 察隅县| 辉南县| 本溪| 高雄市| 烟台市| 彭州市| 车致| 海兴县| 独山县| 普安县| 巍山| 玉门市| 石景山区| 景泰县| 读书| 海口市| 林西县| 西吉县| 彰化市|