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

sizeof(空類/空結構體) 為何等於 1?深度解析

     編輯:關於C++

面試真題引發的思考

某開發者在面試中遇到經典問題:「VC++ 中空類(無任何成員變量與函數)佔用多少字節?」選項為 0、1、4、8。直覺上可能傾向 0 或 4/8(指針大小),但實測 VC6.0、VS2010、g++ (Linux x64) 均輸出 1。為何?

驗證代碼與結果

#include <iostream>
using namespace std;

class ClassA { };           // 空類
class ClassB : public ClassA { }; // 繼承空類
struct StructC { };         // 空結構體

int main() {
    cout << "A: " << sizeof(ClassA) << endl; // 1
    cout << "B: " << sizeof(ClassB) << endl; // 1
    cout << "C: " << sizeof(StructC) << endl; // 1
    return 0;
}

三大主流編譯器(MSVC 32/64-bit、GCC 64-bit)結果一致:1 字節。

核心原因:C++ 標準與對象模型

1. 標準強制要求:完整對象必須擁有非零大小

C++ 標準(ISO/IEC 14882)規定:「完整對象類型的大小必須大於零」。這確保每個對象在內存中擁有唯一地址,使得:

  • 不同對象地址不相等(&a != &b)
  • 數組元素地址正常遞增(&arr[i+1] == &arr[i] + 1)
  • 指針運算、new 分配、標準容器存儲均正常工作

2. 編譯器實現:插入佔位字節

編譯器通常在空類中隱式插入一個 char 類型的佔位成員,使大小為 1。這是最小非零值,兼顧內存對齊與空間效率。

3. 空基類優化(EBO)的特例

雖然 ClassB 繼承自空類 ClassA,但作為完整對象(非基類子對象),ClassB 仍需佔用 1 字節。EBO 僅在「作為基類子對象嵌入派生類時」才將其大小壓縮為 0,不影響獨立實例的大小。

多態與 Name Mangling 的啟示

文中提到 C++ 重載函數通過 Name Mangling(如 _add_int_int)區分,這印證了類型系統在編譯期對「實體身份」的嚴格要求——空類同樣需要唯一的類型標識與內存實體,1 字節正是這一機制的最小代價。

總結

sizeof(空類) == 1 不是編譯器漏洞,而是 C++ 為保證對象模型自洽、內存語義正確而做出的標準化設計決策。理解此點,有助於深入掌握 C++ 對象佈局、繼承優化及標準容器行為。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved