首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 對象內存佈局探秘:從基礎類到多重繼承

     編輯:關於C++

實驗環境與前提

為清晰觀察內存佈局,編譯器結構成員對齊設置為 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

頂層基類在最前,遞歸展開,最後是派生類自身新增成員。

核心規律總結

  • 對象 = 所有基類數據成員(按繼承圖深度優先、從左到右順序)+ 派生類自身數據成員。
  • 虛函數、虛繼承會引入 vptr/vbptr,改變佈局(本文未涉及)。
  • 空基類優化(EBO)可能使空基類不佔用空間(需編譯器支持)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved