單一的一般繼承
可見以下幾個方面:
1. 虛函式表在最前面的位置
2. 成員變數根據其繼承和宣告的順序一次放在後面
3. 在單一繼承中, 被 overwrite 的虛函式在虛函式表中得到更新
多重繼承
我們可以看到
1. 每個父類都有自己的虛函式表
2. 子類的成員函式被放在第乙個父類的表中
3. 記憶體布局中, 父類按照宣告順序一次排列
4. 每個父類的虛表中的 f() 函式都被 overwrite 成了子類的 f(). 這樣做就是為了解決不同父類型別的指標指向同乙個子類例項.
重複繼承
我們可以看到, 最頂端的父類 b 其成員變數存在於 b1 和 b2 中, 並被 b 給繼承下來了. 而在 d 中, 其有 b1 和 b2 的例項, 於是 b 的成員在 d 的例項中存在兩份, 乙份是 b1 繼承來的, 另乙個份是 b1 繼承來的. 所以, 我們使用如下語句, 則會產生二義性編譯錯誤
d d;
d.ib = 0; // 二義性錯誤
d.b1::ib = 1; // ok
d.b2::ib = 2; // ok
鑽石型虛擬多重繼承
結論1. 乙個 virtual base class 只會在 derived class 中存在乙份實體, 無論該基類被繼承多少次
2. (1) 的具體實現是將 d 物件分割成兩部分, 分別是不變區域性和共享區域性. 不變區域性部分, 無論後繼如何演化, 總有固定的偏移量, 所以這部分資料可以直接訪問. 至於共享區域性, 表現出來的就是虛擬繼承的基類子物件, 這一部分資料的位置隨著派生操作而變化, 因此是間接訪問.
3. 一般的策略是存放不變區域性, 然後在每乙個派生物件中插入指標 vbptr, 每乙個指標指向基類子物件
4. 上圖中, 第乙個 vbptr 的值是 -4 和 40, 第二個是 -4 和 24. 40, 24 分別是 b1, b2 到基類子物件的偏移. -4 是 vbptr 到 _vfptr 的偏移.
**:
C 物件記憶體布局
好文要記下來 上 下 玄機逸士系列 補充一點,兩個博文裡面都沒有給出虛基類表中的第一項的解釋,其實第一項就是vbptr到自己類物件位址的偏移量。若沒有虛函式,也就是沒有vfptr,偏移量為0,若有,就為 4 vfptr 在 vbptr之前,所以是 4 玄機逸士的結論 vc 6 其一,只要涉及到虛基類...
C 記憶體物件布局
本章主要介紹了c 類中成員變數 函式物件的在記憶體中布局.當c 類中不包含virtual機制類的函式時,內部nostatic member被包含在每乙個class object之中,就想c struct一樣,而member function雖然含在class宣告之內,卻不出現在object之中,每乙...
C 物件記憶體布局
類中的元素 類成員變數 類成員函式 靜態成員變數 靜態成員函式 虛函式 純虛函式 影響物件大小的元素 類成員變數 虛函式表指標 虛基類指標 記憶體對齊。注 所有的靜態成員變數 靜態成員函式 類成員函式都不會影響物件的大小,純虛函式與虛函式一樣都由虛函式表指標來管理。vftptr vbtptr的初始化...