多重繼承和虛繼承的記憶體布局
c++物件模型
c++ 虛函式表解析
c++在布局以及訪問時間上主要的額外負擔是由virtual引起的,包括:
(1)虛函式機制;(2)虛基類
這篇文章不錯,本文幾個圖來自這裡: 在
c語言中,「資料
」和「處理資料的操作(函式)
」是分開來宣告的,也就是說,語言本身並沒有支援
「資料和函式
」之間的關聯性。在
c++中,通過抽象資料型別(
abstract data type
,adt
),在類中定義資料和函式,來實現資料和函式直接的繫結。
概括來說,在c++
類中有兩種成員資料:
static
、nonstatic
;三種成員函式:
nonstatic data成員被配置於每乙個類物件之內;static data成員被存放在個別類物件之外。
static 和 nonstatic 函式成員被放在個別類物件之外;
virtual函式則按照以下兩個步驟支援:
a. 每個類產生一些(數量等於該類中的虛函式個數)虛函式的指標(指標指向的是虛函式的位址),放在虛函式表中;
b. 每個類物件會產生乙個vptr指標,該指標指向虛函式表。vptr的設定和重置都是由每個類的建構函式、析構函式和拷貝賦值運算子自動完成。每個類含關聯乙個type_info物件用以支援執行時型別識別(runtime type identification,rtt1),它是編譯器生成的特殊型別資訊,包括物件繼承關係、物件本身的描述,rtt1是為多型而生成的資訊,所以只有具有虛函式的物件才會生成。
關於c++物件模型主要的參考書就是stanley b. lippman所著的《深度探索c++物件模型》一書。然而就虛函式表的布局問題,這是乙個與編譯器相關的問題,因此,該書所提到的c++物件模型的布局問題僅可作為參考,而實際不同的編譯器以及同一編譯器的不同版本都可能有不同的實現方式。
例如下面要說的:(1)《深度探索c++物件模型》該書侯捷所譯的版本第9頁提到,虛函式表的第一項是存放type_info引數的,但我實際測試的結果並不是這樣:虛函式表的第一項是第乙個宣告的虛函式位址不是type_info的位址。(2)這篇博文c++物件模型的驗證說明其系統的編譯器中:虛函式表的位址依次增大(例如第乙個虛函式表的位址小於第二個虛函式表的位址),但是我的驗證中虛函式表的位址卻是依次遞減的。(3)同樣是上一條提到的博文中,其編譯器下,虛函式表中每個表項(乙個虛函式的位址)佔四個位元組,而我的g++(gcc 4.4.3)下是佔四個位元組,但是vs2010卻不是這樣。
我驗證的編譯器下,vs2010和gcc 4.4.3下與csdn博主陳皓的文章c++ 虛函式表解析
結論一致。
cout << &a << "\t type_info base物件的位址" << endl;
/*const type_info &b = typeid(base);
cout << &b << "\t type_info base物件的位址"<< endl;*/
cout << (int *)(&d) << "\t 虛函式表位址" << endl;
typedef void (*fun)();
fun fun = (fun)*((int *)*(int *)(&d));
cout << &fun << "\t virtual void test()函式位址" <
1)虛函式按照其宣告順序放於表中。
2)父類的虛函式在子類的虛函式前面。
1)覆蓋的f()函式被放到了虛表中原來父類虛函式的位置。
2)沒有被覆蓋的函式依舊。
1) 每個父類都有自己的虛表。
2) 子類的成員函式被放到了第乙個父類的表中。(所謂的第乙個父類是按照宣告順序來判斷的)
1)
每個基類都有自己的虛表。
2)
子類的成員函式被放到了第乙個基類的表中。
3)
記憶體布局中,其父類布局依次按宣告順序排列。
4)
如果子類重寫了基類的虛函式,例如重寫了基類的虛函式print(),那麼,
每個基類的虛表中的
print()
函式都被
覆蓋成了子類的
print()
。這樣做就是為了解決不同的基類型別的指標指向同乙個子類例項,而能夠呼叫到實際的函式。
C 物件模型 第 1 章 關於物件
1.使用class封裝之後的布局成本 1 class並沒有增加成本,data members直接內含在每乙個class object之中,就像c struct一樣。而member functions雖然被包含在class的宣告之內,但是不出現在object之中。每乙個non inline funct...
《深度探索C 物件模型》 第1章 關於物件
關於物件,首先要和c語言的struct對比,c 的static和nonstatic函式雖然和類繫結在一起,但他們被放在所有的class object之外,c 在布局和時間上的額外負擔是有virtual和多重繼承引起的。1.1 c 物件模式,主要介紹了vptr和vtbl的概念,很多具體的內容還是放到了...
深度探索C 物件模型 第1章 關於物件
1.3 物件的差異 一 簡單物件模型 將指向data member與member function的指標放入到object中,member本身並不放在object中 二 驅動物件模型 object 中包含兩個指標,分別指向data member table與function member table...