叄
多重繼承
注意:在多重繼承下,若有n個基類,則派生類中有n個virtual table.
針對每乙個virtual table,派生類物件中有對應的vptr。這些vptrs將在建構函式中被設立初值。
派生類的虛函式會覆蓋(改寫)其每個基類virtualtable中相應的虛函式索引值。
多重繼承最左端的基類,在派生類中作為主要實體,其virtualtable為主要**,其它基類的virtual table為次要**。
當你將derived物件位址指定給乙個base1指標或derived指標時,被處理的virtualtable是主要**vptr_base1。
故主要**要包含derived的所有虛函式(包括繼承得來的虛函式)。所以其中有base1、base2、derived中的虛函式。
而其它次要**中的專案數不變,只是有些虛函式的索引值被重寫。
涉及多重繼承的指標的轉換
多重繼承的問題主要發生於:派生類物件和其第二或後繼的基類物件之間的轉換。
【對乙個多重派生物件,將其位址指定給「最左端(也就是第乙個)」base class的指標,情況將和單一繼承時相同,因為二者都指向相同的起始位址。需付出的成本只有位址的指定操作而已。至於第二個或後繼的base class的位址指定操作,則需要將位址修改:加上(或減去)介於中間的base class subobject(s)大小】
例如:derived dobj ;
a* pa = &dobj ;
只需要簡單地拷貝位址就行了。
而:derived* pd ;
b* pb = pd ;
需要這樣的內部轉化:
//虛擬c++碼
pb = pd ? (b*)( (char*)pd + sizeof(a) ) : 0 ;
肆
含虛繼承的多重繼承
1、虛基類無資料成員
例:
class a ;
【注意】class a ;實際上並不是空的,它有乙個隱晦的1位元組,那是被編譯器安插進去的乙個char。這是為了使得class a的物件得以在記憶體中配置獨一無二的位址。
當語言支援虛基類時,就會導致一些額外負擔。在派生類中會有乙個額外指標,指標指向乙個相關**,**中存放的或者是虛基類物件,或者是其偏移量。
若虛基類為空,則**中存放的是虛基類物件(即乙個安插位元組)
vc++編譯器的優化:
vc++特別對 空virtual baseclass做了處理。空虛基類的派生類中只有乙個4位元組的指標。沒有安插char,也沒有位元組填充。
(因為安插char的目的是為了空類例項化的物件在記憶體中有位址,而現在其派生類物件中已經有個指標了,其可以取位址,故不需要安插char了)
注意:如果虛基類中有資料成員,則兩種編譯器(「有特殊處理者」和「無特殊處理者」)就會產生完全相同的物件布局。
2、虛基類有資料成員
例:
class a
最終的派生類物件底部是共享虛基類的部分,派生類class b、class c部分的指標指向的虛函式表的前面增加了一項:offset(從物件的開頭算起,到共享虛基類部分的位元組數)
這樣可以快速地訪問到共享虛基類的成員。
問:①為什麼虛繼承不像一般繼承那樣,把基類成員放在頂部,把新增派生類成員放在尾部?
我想是:因為在最後的多重繼承時,要求最終的派生類物件中只有乙份基類成員,故最終派生類會從其各個父類中提取它們各自的派生資料成員。若按一般繼承那樣的物件模型,很容易找到父類中的派生類成員,但難以確定邊界,故難以提取資料。為了提取資料方便,把基類成員放在尾部。
②為什麼虛繼承的派生類中有兩個虛指標?
我想是:因為要實現多型。當基類指標指向派生類中的基類部分時,必須要有指向虛表的指標,才能實現多型。
注意:class d物件模型與一般多重繼承的派生類物件的布局相似,多重繼承最左邊的基類部分的虛表是「主要**」。故class b、class c、class a部分的虛表各不相同。它們都是為了實現多型。
【程式設計風格】一般而言,virtual base class最有效的一種運用形式是:乙個抽象的virtual base class,沒有任何資料成員。
深入探索C 物件模型
深入探索c 物件模型 本書目錄結構如下 第1章 關於物件 object lessons 加上封裝後的布局成本 layout costs for adding encapsulation 1.1 c 模式模式 the c object model 簡單物件模型 a object model 驅動物件模...
整理自用 深入探索c 物件模型(二)
是從第二章開始看起的,通常情況下,如果以後開頭沒有特殊說明,標題中 裡數字代表的是章節序號 1.3 程式轉化語意 情況1 如果類中包含有乙個其他類成員,且這個類成員有預設建構函式。那麼編譯器構建預設建構函式 事實上相當於是呼叫該類成員預設建構函式 注意 其他成員仍然處於未知狀態。例子 class a...
深入探索C 物件模型之物件
物件 一 在c語言中,資料 和 對資料的處理 函式 分開宣告的,也就是說,語言本身並沒有支援 資料和函式 之間的關聯性。例如,typedef struct point3dpoint3d 而在c 中,座標型別和座標數目都可以引數化 template class point type operator ...