C 物件模型的演變及驗證 1

2021-06-10 20:45:28 字數 2731 閱讀 2636

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語言中,資料 和 處理資料的操作 函式 是分開來宣告的,也就是說,語言本身並沒有支援 資料和函式 之...