C/C++中類的存儲方式 收藏
C/C++中類的存儲方式
一、簡單對象的存儲
1、 基本類型對齊原則:
Char 1
Short 2
Int 4
Long 4
Float 4
Double 8
2、 結(jié)構(gòu)體類型對齊原則:
以最大成員類型的對齊方式為準(zhǔn),即當(dāng)需要增長時,增長最大成員類型所占用的字節(jié)數(shù)。
3、 靜態(tài)成員變量不占用類對象的存儲空間原則:
靜態(tài)成員變量所有的類對象共享一份,在靜態(tài)區(qū)域中,并不占用類對象的空間。
4、 沒有任何成員變量的類對象占用一個字節(jié)的空間
驗(yàn)證程序:vc.net2003下運(yùn)行結(jié)果
#include <iostream>
using namespace std;
/*沒有任何數(shù)據(jù)成員的對象類占用一個字節(jié)的空間*/
class A1
{
};
/*靜態(tài)數(shù)據(jù)成員不占用類對象的存儲空間*/
class A2
{
char c1;
static int count;
};
/*當(dāng)只有char類型時,以1個字節(jié)為單位對齊*/
class B1
{
char c1;
char c2;
};
/*與A比較發(fā)現(xiàn),當(dāng)最大為short時,以2個字節(jié)為單位對齊*/
class B2
{
char c1;
short s;
};
/*與A比較發(fā)現(xiàn),當(dāng)最大為int時,以4個字節(jié)為單位對齊*/
class B3
{
char c1;
int i;
};
/*與A比較發(fā)現(xiàn),當(dāng)最大為double時,以8個字節(jié)為單位對齊*/
class B4
{
char c1;
float d;
};
/*與A比較發(fā)現(xiàn),當(dāng)最大為double時,以8個字節(jié)為單位對齊*/
class B5
{
char c1;
double d;
};
/*c s i 占4個字節(jié),d占4個字節(jié)*/
class C1
{
char c;
short s;
int i;
double d;
};
/*d占4個字節(jié),c s i 占4個字節(jié)*/
class C2
{
double d;
char c;
short s;
int i;
};
/*c占1個字節(jié),d從下一個4字節(jié)開始占4個字節(jié),s i在下一個4字節(jié)中*/
class C3
{
char c;
double d;
short s;
int i;
};
/*c s 在頭4個字節(jié)中,d占下四個字節(jié),i 在最后4個字節(jié)中*/
class C4
{
char c;
short s;
double d;
int i;
};
int main()
{
cout << "size of A1 : " << sizeof(A1) << endl; /*1字節(jié)*/
cout << "size of A2 : " << sizeof(A2) << endl; /*1字節(jié)*/
cout << endl;
cout << "size of B1 : " << sizeof(B1) << endl; /*2字節(jié)*/
cout << "size of B2 : " << sizeof(B2) << endl; /*4字節(jié)*/
cout << "size of B3 : " << sizeof(B3) << endl; /*3字節(jié)*/
cout << "size of B4 : " << sizeof(B4) << endl; /*8字節(jié)*/
cout << "size of B5 : " << sizeof(B5) << endl; /*8字節(jié)*/
cout << endl;
cout << "size of C1 : " << sizeof(C1) << endl; /*16字節(jié)*/
cout << "size of C2 : " << sizeof(C2) << endl; /*16字節(jié)*/
cout << "size of C3 : " << sizeof(C3) << endl; /*24字節(jié)*/
cout << "size of C4 : " << sizeof(C4) << endl; /*24字節(jié)*/
system("pause");
return 0;
}
二、繼承下的對象存儲
1、虛表指針占用4個字節(jié)原則
對于一個類而言,在不存在虛函數(shù)的情況下,類的大小等于成員大小之和(按照對其原則),當(dāng)存在虛擬函數(shù)時,由于要保存虛表指針,故多占用4個字節(jié)。
2、子類共享父類的虛表指針原則
在普通繼承下,子類與父類共享一個虛表,子類不需要另外添加內(nèi)存。
3、虛基類表指針占用4字節(jié)原則
在虛繼承的情況下,繼承了多個繼承了同一個父類的中間類的子類只保存了一個同他基類的備份,但每個中間類都需要需要保存指向基類表的指針來指向共同的基類。
#include <iostream>
using namespace std;
class A1
{
int numA1;
};
/*與A1比較,存在虛函數(shù)的情況下,需要保存虛函數(shù)表指針占4個字節(jié)*/
class A2
{
int numA2;
virtual FunA2();
};
/*與A2比較,當(dāng)不存在不同于父類的虛函數(shù)時,子類與父類共享保存虛函數(shù)表的指針*/
class B1 : A2
{
int numB1;
};
/*與A2比較,當(dāng)存在不同于父類的虛函數(shù)時,子類與父類共享保存虛函數(shù)表的指針*/
class B2 : A2
{
int numB2;
virtual FunB2();
};
/*與B1比較,虛繼承需要保存指向虛基類表的指針占4個字節(jié)*/
class B3 : virtual A2
{
int numB3;
};
/*虛繼承下,若子類中有不同于父類的虛函數(shù),則需要不同于父類的指向虛函數(shù)表的指針*/
class B4 : virtual A2
{
int numB4;
virtual FunB4();
};
/*虛繼承下,共同的基類只有一個備份,但每個虛繼承的類中多了一個只想那個虛基類表的指針*/
class C1 : B3, B4
{
int numC1;
};
void main()
{
cout << "sizeof A1 is : " << sizeof(A1) << endl; /* 4 */
cout << "sizeof A2 is : " << sizeof(A2) << endl; /* 8 */
cout << endl;
cout << "sizeof B1 is : " << sizeof(B1) << endl; /* 12 */
cout << "sizeof B2 is : " << sizeof(B2) << endl; /* 12 */
cout << "sizeof B3 is : " << sizeof(B3) << endl; /* 16 */
cout << "sizeof B4 is : " << sizeof(B4) << endl; /* 20 */
cout << endl;
cout << "sizeof C1 is : " << sizeof(C1) << endl; /* 32 */
system("pause");
}
C的內(nèi)存分布:
B3指向虛基類表的指針 4
B3自己的存儲區(qū)域 4
B4自己的指向虛函數(shù)表的指針 4
B4指向虛基類表的指針 4
B4自己的存儲區(qū)域 4
C1自己的存儲區(qū)域 4
基類的存儲區(qū)域 8