對於乙個繼承了多個base class 的物件,將其位址指定給最左端(也就是第乙個)base class的指標,
情況將和單一繼承時相同,因為兩者都指向相同的其實位址。至於第二個或者更後面的base class的
位址指定操作(把derived class物件位址 賦給 第二個base class型別的指標),則需要將位址修改
加上,介於中間的base class subobject(s)大小
如果有這樣的繼承關係
則布局情況
虛擬繼承
一般的布局策略是先安排好derived class 的不變部分,然後再建立其共享部分
如何訪問class 的共享部分呢?
可以選擇在derived class object中安插一些指標,每個指標指向乙個vrtual base class,通過
間接訪問的方式完成訪問。
void point3d:: operator+= (const point3d &rhs)
可以被轉換成這樣:
__vbcpoint2d->_x += rhs.__vbcpoint2d->_x;
__vbcpoint2d->_y += rhs.__vbcpoint2d->_y;
_z += rhs._z;
point2d *p2d = pv3d;
point2d *p2d = pv3d ? pv3d->__vbcpoint2d : 0;
這樣做的缺點很明顯:
1. 每個物件必須針對每個virtual base class 新增乙個額外的指標,這樣virtual base class
越多,object負擔越重。也就是負擔不固定。
解決辦法1:
引入一二virtual base class table。每個virtual base class都會由編譯器安插乙個指標
指向virtual base class table。真正的virtual base class 指標,被放在table中。也就是table中存放
了所有的virtual base class 的指標。每次要訪問直接從virtual base class table中找到相應基類
解決辦法2:
和virtual function table 放在一起,但是virtual base class存放在索引為負的地方,並且只存放偏移
根據object的基址以及取得的偏移就可以找到object中的virtual base class了。
2. 由於虛擬繼承串鏈的加長,會導致間接訪問的層次增加,也就是你想取得從乙個 虛擬繼承來的基類
的 他的虛擬繼承的基類 的成員,就需要兩次間接訪問,層次越多,訪問越慢。
解決辦法:
把所有的virtual base class 的指標都放置在derived class object中,也就是原本需要兩次間接操作的
現在我們把那個第二次間接操作需要的指標直接放在derived class object中去
這是vs2013的虛擬繼承的布局。
然後還有超級複雜的終極版本:
C 物件的記憶體布局 多繼承
多繼承中,乙個派生類可以有多個基類.多繼承是c 頗受爭議的乙個語法特性,它就像一把雙刃劍,在提供便利及強大功能的同時,也帶來了一些容易使人產生錯誤的不便.在此主要說明一下多繼承時物件的記憶體分布 1.與單繼承相同,首先建立基類的物件,但要遵循一定的順序,這個順序是由派生類宣告時決定.2.和單繼承也一...
C 繼承記憶體布局 虛繼承下的多繼承情況
前面介紹了單繼承以及正常多繼承的記憶體分布情況,最後介紹一種虛繼承的情況。同時虛繼承也是解決多繼承二義性的一種手段。首先將 改動如下,base1跟base11是完全一樣的 除了繼承的時候base1是虛繼承,我們先看下單繼承的時候,虛繼承的記憶體分布跟非虛繼承有什麼區別。可以看到虛繼承的記憶體分布要複...
C 多繼承 虛繼承
一,多繼承 include include using namespace std class b1 繼承類c void main 主函式 c類按照順序繼承b2,b1,b4,b3 再按照資料成員定義順序 memberb1,memberb4,memberb3,memberb2 最後是自己的構造器 二,...