以下均爲linux64位編譯器上實驗數據,指針大小爲8字節
1.空類
class N
{};
N n;
sizeof(n) //等於1
編譯器會安插一個char字節以保證其每個實例都有唯一的地址
2.無虛函數無繼承類
class A
{
public:
int a;
char b;
void func(){};
};
A a;
sizeof(a) //等於8
class和struct一樣會滿足內存對齊,a和b成員變量緊挨,不過b變量需要填補3字節以對齊,普通成員函數不佔內存空間。
3.無虛函數繼承類
class B: public A
{
public:
int c;
char d;
void funcB(){};
};
B b;
sizeof(b) //等於16
子類擁有父類成員變量的拷貝。
4.無繼承虛函數類
class C
{
public:
int a;
char b;
virtual void func(){};
};
C c;
sizeof(c) //等於16
C類和A類幾乎一樣,只是func函數改爲虛函數,內存大小增加了8字節,其實就是增加了一個指向虛函數表的指針(我是用的64位編譯器,若是32位編譯器一個指針大小爲4字節,則是增加了4字節),很多編譯器將這個指針vptr放到對象地址最開始處。
5.單繼承虛函數類
class B:public C
{
public:
int a;
char b;
virtual void func(){};
virtual void funcB(){};
};
B b;
sizeof(b) //等於24
b的內存佈局爲
vptr ---> 虛函數表 B::func()(被override)
C的成員 B::funcB()
B的成員
vptr同樣指向虛函數表,表中存放着C和B的虛函數,但是由於B也有虛函數func所以C::func()被複寫爲B::func()
參考:
http://www.cnblogs.com/QG-whz/p/4909359.html#_label0
發現其實不同編譯器不太一樣.