2012-11-10 wcdj
關鍵字:c++物件模型, 訪問私有成員, 虛函式, 虛函式表(vtbl), 虛函式表指標(vptr), 類成員函式指標
在c++中:
有兩種類資料成員:(1) static (2) nonstatic
有三種類成員函式:(1) static (2) nonstatic (3)virtual
c++物件模型的演變過程:
乙個object是一系列的slots,每個slot指向乙個members。在這個簡單模型中,members本身並不放在object之中,只有指向member的指標才放在object內。
此模型提出了一種思想:使用索引的思想,之後被應用到c++的指向成員的指標思想中。
class object本身則內含指向這兩個**的指標,乙個指向data member table,乙個指向member function table。其中,member function table是一系列的slots,每乙個slot指出乙個member function;而data member table則直接含有data本身。
此模型也提出了一種思想:member function table的思想成為以後virtual functions的乙個有效解決方案。
nonstatic data members被置於每乙個class object之內,static data members則被存放在所有的class object之外,並且,static和nonstatic function members也被放在所有的class object之外。
virtual functions則以兩個步驟支援之:
[1] 存在乙個virtual table。每乙個class產生一堆指向virtual functions的指標,並存放在這張表中。(根據虛函式宣告的順序存放)
[2] 每乙個class object被新增了乙個指標,指向相關的virtual table。(這個指標被稱為vptr)
注意:(a) vptr的設定和重置都有每乙個class的constructor、destructor和copy assignment運算子自動完成。
(b) 每乙個class所關聯的type_info object (用以支援runtime type identification, rtti)也經由virtua ltable 被指出來, 通常是放在**的第乙個slot處。(注意實踐表明可能不是這樣)
了解了c++物件模型之後,可以對其進行簡單的驗證,不同的編譯器可能實現有所不同。下面的例子考慮最簡單的情況,暫時不考慮繼承,主要測試以下幾點:
環境:windows server 2003, 32位 + vs2008
(1) 根據物件模型計算類成員偏移量, 並通過偏移量來訪問類成員,包括類的私有成員;
(2) 定義類成員函式指標, 並通過類成員函式指標訪問類成員函式;
/* 2012-11-10 wcdj
* c++虛函式表的例項解析
*/#include // 指定按1位元組對齊
#pragma pack(1)
// 定義普通函式指標
typedef void(*fun)(void);
// 定義類成員函式指標
class base;
typedef void(base::*cfun)(void);
#define callmemfun(obj, pcfun) ( (obj).*(pcfun) )
#define pcallmemfun(pobj, pcfun) ( (pobj)->*(pcfun) )
class base
base(int a, char b): m_ia(a), m_cb(b) {}
virtual ~base() {}
// virtual functions
virtual void f()
virtual void g()
virtual void h()
// non-virtual functions
void test()
void test2()
private:
int m_ia;
char m_cb;
};int main()
/*output:
the size of base: 9
the size of base: 9
&b = 0x12ff3c
*(int *)(&b) = 0x60f3e8
*(int*)(*(int *)(&b)) = 0x4b0701
invork f()
invork g()
invork h()
ia=1
cb=x
this is non-virtual function named test
&base::test = 0x4aedca
&base::test2 = 0x4b263c
this is non-virtual function named test
invork f()
invork g()
this is non-virtual function named test
*/
參考:
[1] c++ 虛函式表解析
[2] 類的普通成員函式的指標
[3] 深度探索c++物件模型,inside the c++ object model
C 物件模型的演變及驗證 2
2012 11 11 wcdj 瑪雅人 的2012年12月21日世界末日前的最後乙個光棍節,果真是乙個人的節日,祝小時爸爸手術順利,早日 本文在前文的基礎上,考慮繼承關係 單繼承 繼續驗證繼承關係下的c 物件模型。先看下什麼叫作覆蓋 override 覆蓋 override,是指派生類中存在重新定義...
c 物件模型1
一 類空間大小及證明 1.乙個沒有任何成員函式的類的空間大小是多少?1位元組2.為什麼是1位元組,而不是0?因為這個類在記憶體中有記憶體位址,這個記憶體位址最少能存1位元組 3.如果這個類新增三個類成員函式,那麼這個類空間的大小是多少?還是1位元組,因為類成員函式不占用類物件的記憶體空間 4.還是給...
C 物件模型 第1章 C 物件模型
多重繼承和虛繼承的記憶體布局 c 物件模型 c 虛函式表解析 c 在布局以及訪問時間上主要的額外負擔是由virtual引起的,包括 1 虛函式機制 2 虛基類 這篇文章不錯,本文幾個圖來自這裡 在 c語言中,資料 和 處理資料的操作 函式 是分開來宣告的,也就是說,語言本身並沒有支援 資料和函式 之...