虛擬繼承、虛函式學習總結
一、虛函式。
其實是比較簡單的,它的存在就是為了給子類繼承,並且提供多個介面,所謂多個介面,就是多型性,它的主要特點就是父類的指標可以指向子類的物件,這樣的話,在繼承上會有好處。例如,某個父類有多個子類,在不知道會呼叫哪乙個子類物件的情況下,可以定義乙個父類的指標 f ,這樣就實現了所謂的「介面」功能,在知道了要使用哪乙個子類的時候,就直接把父類的指標 f 指向那個子類的物件,以後的操作都是採用父類的指標 f ,這樣顯然就有優點了,可以把對子類的操作封裝起來,跟它使用哪乙個子類沒有關係了,因為在被封裝起來的操作裡面操作的物件是父類的指標 f ,然後這些被封裝的操作就提供了乙個「介面」,要用哪乙個類的物件,就把那乙個類物件的位址給父類的指標 f 。
二、虛函式非虛擬繼承
**:
說的是虛函式在記憶體中的格局,講得很好理解。通過 vs2005 除錯檢視記憶體也是一樣的。就是虛函式表。
三、虛擬繼承。
** 另一篇文章寫得很好,也是csdn 部落格上的,《 c++ 虛繼承物件的記憶體布局 》
**:
在《 c++ 物件記憶體布局》有乙個名詞叫做「鑽石型虛擬多重繼承」,之前不知道該怎麼稱呼這種繼承,畫成圖,它們的形狀就像稜形,乙個基類產生兩個子類,兩個子類又同時被另乙個「孫類」虛擬繼承,最簡單的虛擬繼承就是這樣子。
1、 沒有涉及虛函式的虛擬繼承。如果不管內部如何實現,簡單的說就是「孫類」只拷貝一次基類,如果涉及到記憶體布局,那就必須通過 debug ,檢視執行時的記憶體, 《 c++ 虛繼承物件的記憶體布局 》說到了這一點。通過記憶體檢視「孫類」物件的位址,這個位址就相當於有虛函式的虛擬繼承的「 virtual base class table 」簡稱「 vbtbl 」,當然名稱可能有點問題,因為它只是包含用來尋找虛基類表的偏移值,而不是虛基類表的指標。在沒有虛函式的情況下,它儲存的內容同樣有兩項(因為只有乙個基類),第一項為 0 ,因為沒有虛函式,第二項為本位址相對於基類的偏移值。從「孫類」的記憶體中發現,基類的內容放在在最後面,這也跟有虛函式的時候一樣。可能是為了跟有虛函式的時候統一,格式是一樣的,這樣的話,在沒有虛函式的時候,有些是沒有用的,如 b 子類也有個類似於「 vbtbl 」的東西,如果沒有理解錯的話,它應該是沒用的,訪問基類的時候用不著它。在檢視記憶體的時候還發現了一些現象,記憶體裡面沒有函式的位址,只有變數空間,這個大概就是非虛函式跟虛函式的不同吧。通過檢視記憶體可以很好的理解底層的東西。
2、 含有虛函式的虛擬繼承。這就涉及到了虛函式表、虛基類、 vbtbl 。 《 c++ 虛繼承物件的記憶體布局 》裡面說得很詳細,那個「孫」類物件的記憶體結構圖看起來非常的明確,我在 vs2005 裡面檢視,完全一樣。
3、 總結:有虛擬繼承的「孫」類的物件的記憶體格局是這樣的,被虛擬繼承的基類放在最後,子類按順序放在基類的前面。子類的物件的記憶體格局,基類也是放在最後。虛擬繼承的每乙個類都有「 vbtbl 」之類的東西。
虛擬繼承 虛函式,含有虛函式的菱形虛擬繼承
一 虛擬繼承 虛函式 場景 派生類沒有自己的虛函式,只是繼承基類的虛函式 我們看乙個例子 class base virtual void funtest2 int b class derived virtual public base virtual void funtest2 int d type...
C 虛函式學習總結
一 虛函式學習 1.什麼是虛函式?本質不是過載而是覆蓋。2.虛函式有什麼作用?實現多型。同乙個宣告的不同實現。3.子類重寫父類的普通函式和子類重寫父類的虛函式有什麼區別?可以讓成員函式的操作一般化,用基類的指標指向不同的派生類物件時,基類指標呼叫其虛函式成員函式,則會呼叫其真正指向物件的成員函式,而...
C 學習(9)(虛擬繼承虛函式)
虛函式在類的多層繼承時,如果中間類繼承了同乙個基類,那派生類就會繼承兩套基類,產生二義性。同時,虛擬繼承時,派生類要給出虛基類的構造。include 虛擬繼承 using namespace std class person person string getname void setname st...