c++繼承

繼承

語法:

class 子類 :繼承方式  父類

繼承方式:

public: 公有繼承

通過公有繼承-->私有權(quán)限不會被繼承,父類中的公有權(quán)限在子類中還是公有權(quán)限,保護權(quán)限在子類中還是保護權(quán)限

protected:保護繼承

通過保護繼承-->私有權(quán)限不會被繼承,父類中的公有權(quán)限和保護權(quán)限在子類中變?yōu)楸Wo權(quán)限

private:私有繼承

通過私有繼承-->私有權(quán)限不會被繼承,父類中的公有權(quán)限和保護權(quán)限在子類中變?yōu)樗接袡?quán)限

繼承中的對象模型

  • 子類會繼承父類中所有的內(nèi)容,包括了私有屬性
  • 只是我們訪問不到,編譯器給隱藏了

通過vs的Developer Command Prompt工具,可以查看單類的數(shù)據(jù)結(jié)構(gòu)。

查看命令:

cl /d1 reportSingleClassLayout+類名 +空格+ 類所在文件名

繼承中的構(gòu)造和析構(gòu)順序

  • 子類是不會繼承父類的構(gòu)造函數(shù)和析構(gòu)函數(shù)、=號函數(shù)

  • 子類創(chuàng)建對象時,先調(diào)用父類的構(gòu)造,然后調(diào)用自身構(gòu)造

  • 析構(gòu)順序和構(gòu)造順序相反

  • 如果父類中沒有合適默認構(gòu)造,那么子類可以利用初始化列表的方式顯示的調(diào)用父類的其他構(gòu)造

    例:

class Base
{
public:
    Base(int A)
    {
        this->A = A;
    }
private:
    int A;

    
    
};
//利用初始化列表方式 顯示調(diào)用
class Son:public Base
{
public:
    Son(int a) :Base(a)
    {

    }
};

繼承中的同名成員處理

  • 成員屬性 直接調(diào)用先調(diào)用子類,如果想調(diào)用父類 需要作用域

  • 成員函數(shù) 直接調(diào)用先調(diào)用子類,父類的所有版本都會被隱藏,除非顯示用作用域運算符去調(diào)用

    子類+.+父類名::+成員屬性
    子類::+父類名::+\成員函數(shù)
    

繼承中的靜態(tài)成員處理

  • 靜態(tài)成員屬性 子類可以繼承下來
  • 靜態(tài)成員函數(shù) 類似非靜態(tài)成員函數(shù)處理,如果想訪問父類的,加作用域即可

多繼承

  • 多繼承會帶來一些二義性的問題,如果兩個基類中有同名的函數(shù)或者變量,那么通過派生類對象去訪問這個函數(shù)或變量時就不能明確到底調(diào)用從基類1繼承的版本還是從基類2繼承的版本。
  • 解決方式:顯示指定調(diào)用那個基類的版本。
  • 不建議使用多繼承

菱形繼承和虛繼承

兩個派生類繼承同一個基類而又有某個類同時繼承這兩個派生類,這種繼承被稱為菱形繼承或者鉆石型繼承。

菱形繼承

菱形繼承會導(dǎo)致數(shù)據(jù)浪費(出現(xiàn)兩次)解決問題利用虛基類

例:

class Animal
{
public:
    Animal()
    {
        A = 10;
    }
    Animal(int A)
    {
        this->A = A;
    }

    int A;

    
    
};
class Sheep:public Animal
{

};
class Tuo :public Animal
{

};
class SheepTuo :public Sheep, public Tuo
{

};
void test()
{
    SheepTuo st;
    st.Sheep::A = 10;
    st.Tuo::A = 20;
    cout << st.Sheep::A << endl;
    cout << st.Tuo::A << endl;

}

SheepTuo結(jié)構(gòu)圖

數(shù)據(jù)類表.png

虛基類繼承

繼承時在權(quán)限前面,冒號后面加上virtual關(guān)鍵字
vbptr 虛基類指針
指向一張?zhí)摶惐?通過表找到偏移量
找到共有數(shù)據(jù)

例:

class Animal
{
public:
    Animal()
    {
        A = 10;
    }
    Animal(int A)
    {
        this->A = A;
    }

    int A;

    
    
};
class Sheep:virtual public Animal
{

};
class Tuo :virtual public Animal
{

};
class SheepTuo :public Sheep, public Tuo
{

};
void test()
{
    SheepTuo st;
    st.Sheep::A = 10;
    st.Tuo::A = 20;
    cout << st.Sheep::A << endl;
    cout << st.Tuo::A << endl;

}

結(jié)構(gòu)圖:

虛基類結(jié)構(gòu)表.png
此時數(shù)據(jù)只有一份。vbptr是virtual base pointor縮寫,是一個虛指針。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • C++ 繼承 面向?qū)ο蟪绦蛟O(shè)計中最重要的一個概念是繼承。繼承允許我們依據(jù)另一個類來定義一個類,這使得創(chuàng)建和維護一個...
    蘇州丸子閱讀 3,290評論 0 5
  • Android NDK開發(fā)之旅 目錄 C++ 繼承 面向?qū)ο蟪绦蛟O(shè)計中最重要的一個概念是繼承。繼承允許我們依據(jù)另一...
    香沙小熊閱讀 1,218評論 0 0
  • 概念及工方式 保持已有類的特性而構(gòu)造新類的過程稱為繼承。在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)生新類的過程稱為派生。被...
    帥碧閱讀 472評論 1 1
  • 雖然C++中有頭文件機制使得代碼重用十分高效,但是,文件層面的相互包含(include)仍舊顯得太過笨重。同時,面...
    青暮云閱讀 434評論 0 0
  • 為什么要進行網(wǎng)關(guān)限流? 在前面我們介紹的游戲服務(wù)端架構(gòu)中,客戶端通過Socket連接直連網(wǎng)關(guān),所有請求都需要經(jīng)過網(wǎng)...
    MaxwellGames閱讀 2,630評論 0 6

友情鏈接更多精彩內(nèi)容