首先: 以下所有试验在32位机,VC.Net2003上运行。 class的存储空间有四点需要注意。
1。默认情况下以最大储存空间变量对齐。double-8,int-4,char-1,short-2,float-4,指针-4,虚函数-4,其实虚函数就是一个指针。以最大的对齐。存储空间必须是要对齐的字节个数的整数倍。
2。 变量及虚函数的存储位置首地址必须是自身所占字节个数的整数倍。 3。可以使用#pragma pack设置要对齐的字节个数,pack()中的值只能是1,2,4,8,16,其他值无效,无效时以第1条,最大存储空间的变量为准。并且当设置的值超 过了最大变量存储字节数的时候,也设置无效,取成员变量中最大字节数的那个为准。
4。成员变量和虚函数(包括虚拟析构函数)占存储空间,一般 成员函数,静态成员函数,静态成员变量不占存储空间。在VC.Net下,成员变量和虚函数分开计算,分别补齐。但是在c++builder里,ms是算在 一起的。所以下面这份代码在c++builder里运行估计结果会有差异。
C++代码
#include <stdio.h>
class a
{
char d2;
//0,7
double d1;
//8-15,
int d3;
//16-19,
char d4;
//20,
short d5;
//22-23,
float d6;
//24-27,31 };
class a0{
double d1;
//0-7,
char d2;
//8,
short d5;
//10-11,
char d4;
//12,
int d3;
//16-19,
float d6;
//20-23,
};
class a1
{
char d2;
//0,7
double d1;
//8-15,
int d3;
//16-19,
char d4;
//20,
short d5;
//22-23,
float d6;
//24-27,31 a1(){} ~a1(){}
void fn1(){}
virtual
void fn2(){}
//32-35,39
};
class a2
{
double d1;
//0-7,
char d2;
//8,
short d5;
//10-11,
char d4;
//12,
int d3;
//16-19,
float d6;
//20-23, a2(){}
virtual ~a2(){}
//24-27,
void fn1(){}
virtual
void fn2(){}
//28-31, };
#pragma pack(1)
class a11
{
char d2;
//0,
double d1;
//1-8,
int d3;
//9-12,
char d4;
//13,
short d5;
//14-15,
float d6;
//16-19, a11(){} ~a11(){}
void fn1(){}
virtual
void fn2(){}
//20-23,
};
#pragma
#pragma pack(2)
class a12
{
char d2;
//0,1
double d1;
//2-9,
int d3;
//10-13,
char d4;
//14-15,
short d5;
//16-17,
float d6;
//18-21, a12(){} ~a12(){}
void fn1(){}
virtual
void fn2(){}
//22-25,
};
#pragma
#pragma pack(4)
class a14
{
char d2;
double d1;
int d3;
char d4;
short d5;
float d6; a14(){} ~a14(){}
void fn1(){}
virtual
void fn2(){}
};
#pragma
#pragma pack(16)//16这个值无效,因为所有成员变量中,最大的为double的8,超过了8无效,仍然取8
class a116
{
char d2;
//0,7
double d1;
//8-15,
int d3;
//16-19,
char d4;
//20,
short d5;
//22-23,
float d6;
//24-27,31 a116(){} ~a116(){}
void fn1(){}
virtual
void fn2(){}
//32-35,39
};
#pragma
#pragma pack(3)//3这个值无效,取默认double的8
class a13
{
char d2;
//0,7
double d1;
//8-15,
int d3;
//16-19,
char d4;
//20,
short d5;
//22-23,
float d6;
//24-27,31 a13(){} ~a13(){}
void fn1(){}
virtual
void fn2(){}
//32-35,39
};
#pragma
class b
{
char d1;
int d2;
short d3;
};
class b0 {
char d1;
short d2;
char d3; };
class b1 {
short d1;
char d2; };
#pragma pack(4)//设置无效,因最大的为short的2,设置4无效,仍然取2
class b14
{
short d1;
char d2; };
#pragma
int _tmain(
int argc, _TCHAR* argv[]) {
char* pInt; printf(
"sizeof(char)=%d ",
sizeof(
char));
//1 printf(
"sizeof(double)=%d ",
sizeof(
double));
//8 printf(
"sizeof(int)=%d ",
sizeof(
int));
//4 printf(
"sizeof(short)=%d ",
sizeof(
short));
//2 printf(
"sizeof(float)=%d ",
sizeof(
float));
//4 printf(
"sizeof(char*)=%d ",
sizeof(pInt));
//4 printf(
"sizeof(a)=%d ",
sizeof(a));
//32 printf(
"sizeof(a0)=%d ",
sizeof(a0));
//24 printf(
"sizeof(a1)=%d ",
sizeof(a1));
//40 printf(
"sizeof(a2)=%d ",
sizeof(a2));
//32 printf(
"sizeof(a11)=%d ",
sizeof(a11));
//24 printf(
"sizeof(a12)=%d ",
sizeof(a12));
//26 printf(
"sizeof(a14)=%d ",
sizeof(a14));
//28 printf(
"sizeof(a116)=%d ",
sizeof(a116));
//40 printf(
"sizeof(a13)=%d ",
sizeof(a13));
//40 printf(
"sizeof(b)=%d ",
sizeof(b));
//12 printf(
"sizeof(b0)=%d ",
sizeof(b0));
//6 printf(
"sizeof(b1)=%d ",
sizeof(b1));
//4 printf(
"sizeof(b14)=%d ",
sizeof(b14));
//4
return 0; }
以上注释中的结果是在32位机,VC.Net2003下的结果。
如果是在TC3.0上的话,由于tc是16位编译器,结果会不一样。
在tc里char-1,int-2,short-2,float-4,double-8,指针-2。所有均为紧凑对齐,没有字节对齐。即相当于pack(1)。
具体结构,大家可以自行试验。
在linux下用g++编译后结构也不同:结果如下
sizeof(char)=1
sizeof(double)=8
sizeof(int)=4
sizeof(short)=2
sizeof(float)=4
sizeof(char*)=4
sizeof(a)=24
sizeof(a0)=24
sizeof(a1)=28
sizeof(a2)=28
sizeof(a11)=24
sizeof(a12)=26
sizeof(a14)=28
sizeof(a116)=28
sizeof(a13)=28
sizeof(b)=12
sizeof(b0)=6
sizeof(b1)=4
sizeof(b14)=4
可见在g++中,不会跟double的对齐,而是统一跟4对齐。由b,b0,b1也可以看出g++也是和最大成员变量看齐
唯一区别就是g++中最大的是4,而VC.Net中最大的为8。
至于vc.net编译的时候显示的warning中说pack中的值可以为16,就不知道怎么回事了?
难道有占16个字节的基本类型?
以上注释中的结果是在32位机,VC.Net2003下的结果。
如果是在TC3.0上的话,由于tc是16位编译器,结果会不一样。
在tc里char-1,int-2,short-2,float-4,double-8,指针-2。所有均为紧凑对齐,没有字节对齐。即相当于pack(1)。
具体结构,大家可以自行试验。
在linux下用g++编译后结构也不同:结果如下
sizeof(char)=1
sizeof(double)=8
sizeof(int)=4
sizeof(short)=2
sizeof(float)=4
sizeof(char*)=4
sizeof(a)=24
sizeof(a0)=24
sizeof(a1)=28
sizeof(a2)=28
sizeof(a11)=24
sizeof(a12)=26
sizeof(a14)=28
sizeof(a116)=28
sizeof(a13)=28
sizeof(b)=12
sizeof(b0)=6
sizeof(b1)=4
sizeof(b14)=4
可见在g++中,不会跟double的对齐,而是统一跟4对齐。由b,b0,b1也可以看出g++也是和最大成员变量看齐
唯一区别就是g++中最大的是4,而VC.Net中最大的为8。
至于vc.net编译的时候显示的warning中说pack中的值可以为16,就不知道怎么回事了?
难道有占16个字节的基本类型?