潘凱 C 物件布局及多型實現的探索 十三

2021-04-13 08:55:20 字數 4141 閱讀 5181

**中所定義類的簡單說明

c000:空類。

c010:帶普通成員函式及/或變數的頂層類。

c011:帶普通成員函式及/或變數的頂層類。

c012:帶靜態成員函式及變數的頂層類。

c013:從c010繼承的有成員變數及覆蓋父類普通成員函式的類。

c014:從c011繼承的空類。

c015:從c010,c011繼承的空類。

c016:從c015繼承帶成員函式及/或變數的類。

c020:從c010虛繼承的帶有自己的成員變數的類。

c021:從c010虛繼承的帶有自己的成員變數的類。

c030:從c020,c021繼承的類。

c040:帶虛函式的頂層類。

c041:帶虛函式及變數的頂層類。

c042:帶虛函式及變數的頂層類。

c043:帶兩個虛函式的頂層類。

c050:從c041繼承的空類。

c051:從c041,c042繼承的空類。

c071:從c043繼承並重寫父類第乙個虛函式的類。

c082:從c041,c042繼承帶自己定義虛函式並重寫父類的虛函式的類。

c100:從c041虛繼承的帶成員變數的類。

c101:從c041虛繼承的帶成員變數的類。

c110:從c100,c101繼承的帶成員變數的類。

c140:從c041虛繼承並重寫父類的虛函式的類。

c141:從c041虛繼承並重寫父類的虛函式的類。

c150:從c140,c141繼承的類。

c160:從c041虛繼承帶有自定義虛函式並重寫父類的虛函式的類。

c161:從c041虛繼承帶有自定義虛函式並重寫父類的虛函式的類。

c170:從c160,c161繼承的類。

源**附件為打包的原始碼和vc7.1工程檔案,解開後可自己排程執行。

(附件請到

#include

#include

using namespace std;

struct c000

;struct c010

void foo()

char c_;

};struct c011

char c1_;

char c2_;

};struct c012

int foo()

char c_;

static int i_;

};int c012::i_ = 1;

struct c013 : public c010

void foo()

char c1_;

};struct c014 : private c011

;struct c015 : public c010, private c011

;struct c016 : c015

int i_;

};struct c020 : public virtual c010

char c_;

};struct c021 : public virtual c010

char c_;

};struct c030 : public c020, public c021

char c_;

};struct c040

};struct c041

virtual void foo()

char c_;

};struct c042

virtual void foo2() {}

char c_;

};struct c043

virtual void foo2() {}

};struct c050 : c040

;struct c051 : public c041, public c042

;struct c071 : c043

};struct c082 : public c041, public c042

virtual void foo() {}

virtual void foo2() {}

virtual void foo3() {}

char c_;

};struct c100 : public virtual c041

char c_;

};struct c101 : public virtual c041

char c_;

};struct c110 : public c100, public c101

char c_;

};struct c140 : public virtual c041

virtual void foo()

char c_;

};struct c141 : public virtual c041

virtual void foo()

char c_;

};struct c150 : public c140, public c141

virtual void foo()

char c_;

};struct c160 : public virtual c041

virtual void foo()

virtual void f160()

char c_;

};struct c161 : public virtual c041

virtual void foo()

virtual void f161()

char c_;

};struct c170 : public c160, public c161

virtual void foo()

virtual void f170()

char c_;

};#define print_size(class_name) /

cout << "the size of " << #class_name << " is " << sizeof(class_name) << endl;

#define print_detail(class_name, object_name) /

cout << "the detail of " << #class_name << " is "; /

for (int i = 0; i < sizeof(object_name); ++i) /

cout << setw(0) << dec << endl;

#define print_size_detail(class_name) /

print_size(class_name) /

class_name _##class_name; /

print_detail(class_name, _##class_name)

#define lf /

cout << endl;

template

void *

get_obj_addr(const t & obj)

void *

get_vp_addr(void * start, int offset)

void *

get_vt_addr(void * vp)

void *

get_vti_val(void * vt, int idx)

#define print_vtable_item(obj, vpoffset, index) /

#define print_obj_adr(obj) /

cout << #obj << "'s address is : " << hex << get_obj_addr(obj) << dec << endl;

#define print_pt(pt) /

cout << #pt << "'s value is : " << hex << pt << dec << endl;

struct __declspec(novtable) c180

//struct c180

virtual foo()

};struct c190 : public c180

virtual foo()

};int

main(int argc, char * argv)

//pk change object's type by force

return 0;

}

潘凱 C 物件布局及多型實現的探索 二

帶虛函式的類的物件布局 1 如果類中存在虛函式時,情況會怎樣呢?我們知道當乙個類中有虛函式時,編譯器會為該類產生乙個虛函式表,並在它的每乙個物件中插入乙個指向該虛函式表的指標,通常這個指標是插在物件的起始位置。所謂的虛函式表實際就是乙個指標陣列,其中的指標指向真正的函式起始位址。我們來驗證一下,定義...

潘凱 C 物件布局及多型實現的探索 五

普通成員函式的呼叫 從這部分開始我們除了利用記憶體的資訊列印來進行探索外,更多的會通過跟蹤和觀察編譯器產生的彙編 來理解編譯器對這些語言特性的實現方式。彙編方面知識的討論超出了本文的範圍,我只對和我們討論相關的彙編 進行解析。理解本文要討論的知識並不需要有很完整的彙編知識,但必須了解起碼的概念。下面...

C 物件布局及多型實現的探索

虛函式的類的物件布局 1 如果類中存在虛函式時,情況會怎樣呢?我們知道當乙個類中有虛函式時,編譯器會為該類產生乙個虛函式表,並在它的每乙個物件中插入乙個指向該虛函式表的指標,通常這個指標是插在物件的起始位置。所謂的虛函式表實際就是乙個指標陣列,其中的指標指向真正的函式起始位址。我們來驗證一下,定義乙...