C++深入探究不同的繼承體系
聲明:
本文的測試環(huán)境為Windows平臺下的VS2013環(huán)境
單繼承
一個子類只有一個父類。這類繼承方式是最為簡單的。具體可以參考繼承 上篇中的例子。這里給出簡單的圖示即可:
多繼承
一個子類有兩個或兩個以上的直接父類,這樣的繼承關(guān)系稱之為多繼承。
圖解:
注意事項:
①在多繼承的場景下,建議在繼承的每一個基類名稱前都加上繼承方式,如果不加,可能無法達到我們的預期結(jié)果。
結(jié)論:
class修飾的類,如果不顯式添加繼承方式,默認是private
struct修飾的類,如果不顯式添加繼承方式,默認是public
②多繼承的對象模型隨著子類繼承基類的順序變化而變化
該如何理解上面這句話呢?
來看這兩種情況:
Ⅰ、先繼承Base1,再繼承Base2
Ⅱ、先繼承Base2,再繼承Base1
菱形繼承
概念
了解了上面的兩種繼承方式,下面我們介紹一種單繼承與多繼承有機結(jié)合的產(chǎn)品,他就是菱形繼承!
它的圖解如下:
存在的問題
1、存在二義性問題
最頂層基類成員在最底層子類中存在兩份,如果直接通過最底層子類訪問最頂層的基類成員時,會出現(xiàn)訪問不明確問題。
2、存在數(shù)據(jù)冗余問題
我們來分析一下最底層子類的對象模型:
這里的最頂層基類為了說明問題,只有一個成員變量,但是實際中基類中的內(nèi)容往往很多,數(shù)據(jù)量很大。如果不解決這個問題,那將會存在著嚴重的空間浪費。這是不允許的!
解決方案
解決辦法:
可見,讓訪問明確化并不能直接解決問題!而真正能夠解決問題的是采用菱形虛擬繼承。這個接下來就會介紹到。
菱形虛擬繼承
什么是菱形虛擬繼承?
我們先不著急回答這個問題,首先我們應該搞明白什么是虛擬繼承!!
虛擬繼承
什么是虛擬繼承
使用虛擬關(guān)鍵字virtual修飾的繼承稱之為虛擬繼承
虛擬繼承存在的意義就是 :為了解決菱形繼承存在的二義性和數(shù)據(jù)冗余的問題
內(nèi)存層面理解虛擬繼承
虛擬繼承和普通單繼承的區(qū)別
主要有4點,具體如下:
虛擬繼承+菱形繼承
菱形虛擬繼承實現(xiàn)如下:
也即:
class Base { protected: int _b; }; class Derived1 : virtual public Base { protected: int _d1; }; class Derived2 : virtual public Base { protected: int _d2; }; class D : public Derived1, public Derived2 { public: D() { } void Func() { _b = 1; _d1 = 2; _d2 = 3; } protected: int _dd; }; int main() { D d; d.Func(); return 0; }
分析執(zhí)行過程及d的對象模型:
總結(jié):菱形虛擬繼承是通過讓最頂層基類的成員在最底層子類中只存儲一份的方式來解決的。
到此這篇關(guān)于C++深入探究不同的繼承體系的文章就介紹到這了,更多相關(guān)C++繼承內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言如何實現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))
這篇文章主要介紹了C語言如何實現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08VC++?2019?"const?char*"類型的實參與"LPCTSTR"
這篇文章主要給大家介紹了關(guān)于VC++?2019?"const?char*"類型的實參與"LPCTSTR"類型的形參不兼容的解決方法,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2023-03-03