先来看几段简单的代码:
case1:
#include <iostream>
using namespace std;
class Basic{
private:
int a;
int b;
char c;
int d;
public:
void foo(){return a;}
//public:
// virtual int x(){return a;}
};
int main(){
cout<<"Size of class:"<<sizeof(Basic);
Basic a;
cout<<endl<<"sizeof object :"<<sizeof(a)<<endl;
system("pause");
return 1;
}
此时将会输出sizeof class:16 /n sizeof object :16
在class中成员变量按照顺序按照对齐要求在内存中排列,而普通成员函数在编译时是静态绑定,类调用时就象调用库函数一样,所以类空间中没有为普通成员函数分配空间;由于是对齐方式,因此char同其他的int变量一样也是4字节。这样算下来一共有4×4=16.
case2:
#pragma pack(2)
#include <iostream>
using namespace std;
class Basic{
private:
int a;
int b;
char c;
int d;
//public:
// virtual int x(){return a;}
};
int main(){
cout<<"Size of A:"<<sizeof(Basic);
Basic a;
cout<<endl<<"sizeof object a:"<<sizeof(a)<<endl;
system("pause");
return 1;
}
此时将会输出:sizeof class:14 /n sizeof object :14
#pragma pack(n)
上例中对齐方式由于没有设置,因此默认对齐为4字节对齐(vs2005),此时用预编译命令进行设置为2字节对齐。注意,n的取值只能为2的整数幂,即1,2,4,8……如果非此类数,在警告级为2级以上的情况下会发出设置对齐字错误的警告,设置失败,此时仍然按照默认的4字节进行对齐。
case3:
#include <iostream>
using namespace std;
class Basic{
private:
int a;
int b;
char c;
int d;
public:
virtual int foo1(){return a;}
virtual int foo2(){return a;}
};
int main(){
cout<<"Size of A:"<<sizeof(Basic);
Basic a;
cout<<endl<<"sizeof object a:"<<sizeof(a)<<endl;
system("pause");
return 1;
}
此时会输出:sizeof class:18 /n sizeof object :18
在一个虚类中,函数和纯虚函数是动态绑定的,编译时需要一个指针指向一个虚函数表,所以当类中有虚函数时,类的内存分配为 成员变量+虚函数表指针(4个字节,多个虚函数也只有一个该指针)。
case4:
#pragma pack(2)
#include <iostream>
using namespace std;
struct a
{
__int32 i;
__int8 c[5];
double* p;
__int16 j;
};
int main(){
cout<<endl<<"sizeof struct a:"<<sizeof(a)<<endl;
system("pause");
return 1;
}
输出:sizeof struct a::16
记住一点:内存对齐是为了加快对内存的访问速度来的!