我發現MSVC和GCC編譯器爲每個類實例分配至少一個字節,即使這個類是一個沒有成員變量(或者只有靜態成員變量)的謂詞。以下代碼說明了這一點。爲什麼沒有成員變量的C++類佔用空間?
#include <iostream>
class A
{
public:
bool operator()(int x) const
{
return x>0;
}
};
class B
{
public:
static int v;
static bool check(int x)
{
return x>0;
}
};
int B::v = 0;
void test()
{
A a;
B b;
std::cout << "sizeof(A)=" << sizeof(A) << "\n"
<< "sizeof(a)=" << sizeof(a) << "\n"
<< "sizeof(B)=" << sizeof(B) << "\n"
<< "sizeof(b)=" << sizeof(b) << "\n";
}
int main()
{
test();
return 0;
}
輸出:
sizeof(A)=1
sizeof(a)=1
sizeof(B)=1
sizeof(b)=1
我的問題是爲什麼編譯器需要它?我能想出的唯一原因是確保所有成員var指針都不相同,因此我們可以通過比較指向它們的指針來區分A或B類型的兩個成員。但是在處理小尺寸容器時,這樣做的代價非常嚴重。考慮到可能的數據對齊,我們可以得到每個類沒有變量(?!)的16個字節。假設我們有一個自定義容器,通常會容納幾個int值。然後考慮一個這樣的容器數組(大約有1000000個成員)。開銷將是16 * 1000000!它可能發生的典型情況是一個帶有存儲在成員變量中的比較謂詞的容器類。另外,考慮到類實例應該總是佔用一定的空間,調用A()(value)時應該期望什麼類型的開銷?
只是爲了確認您的懷疑:*除非是位域(9.6),否則大多數派生對象的大小應爲非零,並佔用一個或多個字節的存儲空間。基類子對象可能具有零大小。* – chris 2014-09-11 12:00:37
供參考:大小爲*的子對象被允許。所以,如果你從這樣一個空的類派生出來並添加另一個x的成員,那麼你的派生類型的大小也是x。這就是所謂的「空基類優化」 – sellibitze 2014-09-11 12:04:26
我相信你有幾個問題重疊在那裏。沒有必要在容器中「存儲」大量沒有成員的類。畢竟,由於沒有數據,它們之間沒有區別。但是,沒有成員的類在C++中的大小不爲零並不意味着有成員的類將會產生不必要的開銷。然而,內存對齊問題是一個獨立的問題,並不限於C++。 – AlefSin 2014-09-11 12:05:19