某開發者在面試中遇到經典問題:「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++ 標準(ISO/IEC 14882)規定:「完整對象類型的大小必須大於零」。這確保每個對象在內存中擁有唯一地址,使得:
&a != &b)&arr[i+1] == &arr[i] + 1)new 分配、標準容器存儲均正常工作編譯器通常在空類中隱式插入一個 char 類型的佔位成員,使大小為 1。這是最小非零值,兼顧內存對齊與空間效率。
雖然 ClassB 繼承自空類 ClassA,但作為完整對象(非基類子對象),ClassB 仍需佔用 1 字節。EBO 僅在「作為基類子對象嵌入派生類時」才將其大小壓縮為 0,不影響獨立實例的大小。
文中提到 C++ 重載函數通過 Name Mangling(如 _add_int_int)區分,這印證了類型系統在編譯期對「實體身份」的嚴格要求——空類同樣需要唯一的類型標識與內存實體,1 字節正是這一機制的最小代價。
sizeof(空類) == 1 不是編譯器漏洞,而是 C++ 為保證對象模型自洽、內存語義正確而做出的標準化設計決策。理解此點,有助於深入掌握 C++ 對象佈局、繼承優化及標準容器行為。