繼承
語法:
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縮寫,是一個虛指針。