為清晰觀察內存佈局,編譯器結構成員對齊設置為 1 字節(默認通常為 8 字節)。Debug 模式下未初始化內存填充 0xCC,Release 模式可能為隨機值或 0。
struct c000 {}; 大小為 1 字節(佔位符),確保不同對象擁有唯一地址。
struct c010 { c010() : c_(0x01) {} char c_; }; // 大小 1,內存值 01
struct c011 { c011() : c1_(0x02), c2_(0x03) {} char c1_, c2_; }; // 大小 2,內存值 02 03
對象內存按聲明順序連續存儲數據成員,構造函數負責初始化。
struct c012 {
static int sfoo() { return 1; }
int foo() { return 1; }
char c_;
static int i_;
};
int c012::i_ = 1;
c012 大小仍為 1 字節(僅 c_),0xCC 表示未初始化。結論: 普通成員函數、靜態成員函數、靜態數據成員均不出現在對象內存中。成員函數通過編譯器靜態綁定(傳遞 this 指針),靜態成員類似全局變量但帶類作用域。
struct c014 : private c011 {}; // 大小 2,內容 02 03
子類對象包含父類所有數據成員,繼承方式(public/private/protected)只影響「能見度」,不影響內存佈局。父類成員由父類構造函數初始化。
struct c015 : public c010, private c011 {}; // 大小 3,內容 01 02 03
按聲明順序依次排列基類子對象:最左基類(c010)在前,後續基類緊接其後。
struct c016 : c015 { c016() : i_(1) {} int i_; }; // 大小 7 (3+4),內容 01 02 03 01 00 00 00
頂層基類在最前,遞歸展開,最後是派生類自身新增成員。