c++對象模型中提到:需要多少內存才能夠表現一個class object?一般而言要有:
1 其nonstatic data members的總和大小;
2 加上熱河由於alignment的需求而填補上去的空間(在32位計算機上,通常alignment爲4bytes(32位),使得bus的運輸量達到最高效率)
3 加上爲了支持virtual而由內部產生的任何額外負擔。
舉例1:
class ZooAnimal {
public:
ZooAnimal();
virtual ~ZooAnimal();
..
virtual void rotate();
protected:
int loc;
string name;
};
聲明ZooAnimal za("zoey")之後,對象在堆中的佈局應該是
int loc(4個字節)+string name(8個字節,一個4字節的字符指針和一個用來表示長度的整數)+vptr(4個字節,指向virtual table的地址)=16字節!!
對於上面的例子,如果去除類中定義的virtual function(即去除 virtual ~ZooAnimal()和 virtual void rotate()兩個虛函數),那麼所佔內存變爲了12字節(沒有了vptr)。
注意:虛函數的存在導致了vptr, 如果沒有虛函數,那麼也就沒有vptr了。
當然,如果類虛繼承自另外一個類,那麼也會有4個字節的額外負擔,指向virtual base class subobject的地址。
舉例2:
class zooanimal
{
}
聲明一個空類,調用命令
zooanimal z;
sizeof(z)輸出1個字節,不是0. 這個char字節是被編譯器自動安插進去的,目的使得這個class的兩個objects得以在內存中配置獨一無二的地址。這樣 zooanimal y,z.
&y != &z;
舉例3:
class concrete1{
public:
//....
private:
int val;
char bit1;
};
顯然concrete1對象的大小爲 4字節(int)+1個字節(char bit1)+ padding(3個字節)=8個字節!
然而:
class concrete2: public concrete1{
public:
//....
private:
char bit2;
}
注意此時concrete2對象的大小不是 4字節(int)+1個字節(char bit1)+1字節(char bit2)+padding(2個字節)=8個字節
而是8個字節(concrete1的大小)+1個字節(char bit2)+padding(3個字節)=12個字節;
同理
class concrete3: public concrete2{
public:
//....
private:
char bit3;
}
大小爲 16個字節!!!這樣浪費空間的目的是爲了避免出現concrete1對象向concrete2對象賦值時發生bug。