類所占內存的大小是由成員變量(靜態變量除外)決定的,成員函數(這是籠統的說,后面會細說)是不計算在內的。
示例如下:
(一)
class CBase
{
};
sizeof(CBase)=1;
為什么空的類什么都沒有是 1 呢?
c++要求每個實例在內存中都有獨一無二的地址。空類也會被實例化,所以編譯器會給空類隱含的添加一個字節,這樣空類實例化之后就有了獨一無二的地址了。所以空類的 sizeof 為 1。
(二)
class CBase
{
int a;
char p;
};
sizeof(CBase)=8;
記得對齊的問題,這點和 struct 的對齊原則很像!int 占 4 字節,char 占一字節,補齊 3 字節。
(三)
class CBase
{
public:
CBase(void);
virtual ~CBase(void);
private:
int a;
char *p;
};
sizeof(CBase)=12
C++ 類中有虛函數的時候有一個指向虛函數的指針,在 32 位系統分配指針大小為 4 字節。無論多少個虛函數,只有這一個指針,4 字節。注意一般的函數是沒有這個指針的,而且也不占類的內存。
(四)
class CChild : public CBase
{
public:
CChild(void);
~CChild(void);
virtual void test();
private:
int b;
};
sizeof(CChild)=16;
可見子類的大小是本身成員變量的大小加上父類的大小。其中有一部分是虛擬函數表的原因,父類子類共享一個虛函數指針。
(五)
#include<iostream.h>
class a {};
class b{};
class c:public a
{
virtual void fun()=0;
};
class d:public b,public c
{
};
int main()
{
cout<<"sizeof(a)"<<sizeof(a)<<endl;
cout<<"sizeof(b)"<<sizeof(b)<<endl;
cout<<"sizeof(c)"<<sizeof(c)<<endl;
cout<<"sizeof(d)"<<sizeof(d)<<endl;
return 0;
}
sizeof(a)=1
sizeof(b)=1
sizeof(c)=4
sizeof(d)=8
注意第三種情況和第四種情況。
(六)
#include<iostream>
using namespace std;
class A
{
char a[3];
public:
virtual void fun1(){};
};
class B : public virtual A
{
char b[3];
public:
virtual void fun2(){};
};
class C : public virtual B
{
char c[3];
public:
virtual void fun3(){};
};
int main()
{
cout << sizeof(A) << endl; // 8
cout << sizeof(B) << endl; // 8(A) + 12(B)
cout << sizeof(C) << endl; // 8(A) + 12(B) + 12(C)
return 0;
}
sizeof(A)=8
sizeof(B)=20
sizeof(c)=32
注意,虛繼承的時候A B C三個類不僅不會共享虛基類指針,也不會共享虛表指針,要和普通繼承區分開來。
具體分析如下:
class A size(8):
+---
0 | {vfptr}
4 | a
| <alignment member> (size=1)
+---
class B size(20):
+---
0 | {vfptr}
4 | {vbptr}
8 | b
| <alignment member> (size=1)
+---
+--- (virtual base A)
12 | {vfptr}
16 | a
| <alignment member> (size=1)
+---
class C size(32):
+---
0 | {vfptr}
4 | {vbptr}
8 | c
| <alignment member> (size=1)
+---
+--- (virtual base A)
12 | {vfptr}
16 | a
| <alignment member> (size=1)
+---
+--- (virtual base B)
20 | {vfptr}
24 | {vbptr}
28 | b
| <alignment member> (size=1)
+---
總結
空的類是會占用內存空間的,而且大小是 1,原因是 C++ 要求每個實例在內存中都有獨一無二的地址。
(一)類內部的成員變量:
- 普通的變量:是要占用內存的,但是要注意對齊原則(這點和 struct 類型很相似)。
- static 修飾的靜態變量:不占用內容,原因是編譯器將其放在全局變量區。
(二)類內部的成員函數:
- 普通函數:不占用內存。
- 虛函數:有一個指向虛函數的指針,要占用 4 個字節,用來指定虛函數的虛擬函數表的入口地址。所以一個類的虛函數所占用的地址是不變的,和虛函數的個數是沒有關系的。
說明:此博文轉載之http://blog.sina.com.cn/s/blog_69c189bf0100mkeu.html