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