C++中对象的大小
需要多少内存才能表现一个class object?一般而言要有:
n 其nonstatic data members的总和大小;
n 加上任何由于字节对齐需要而填充上去的空间(可能存在与members之间,也可能存在于集合体边界);
n 加上为了支持virtual而由内部产生的任何额外负担。
C++中实际对象的大小,不同编译器的实现是不一样的,以下仅讨论.net2008,其他编译的可能出现的结果以下也做了分析和猜测。在反推不同编译器实现的C++对象的大小时,对齐是一个很重要也容易被遗忘的问题。
class A{};
看上去一个空的类A事实上并不是空的,它有一个隐含的1byte,那是被编译器安插进去的一个char,这使得这个class的两个objects得以在内存中配置独一无二的地址:
A a,b;
If ( &a == &b ) cerr<<”yipes!”<<endl;
class B:public virtual A{};
B类是对A类的虚继承,B中一般会有指向A的实例的指针,在IA-32下为4bytes。这里不同编译器的实现差别很大,有的编译器在B的对象中也会保留A类的那个隐含的char,于是就有1+4=5个bytes,再考虑对齐,有些编译器产生的结果为8bytes,但是在.net2008中优化过了,不会有A中的char,也就不需要对齐,只有4bytes大小
class C:public virtual A{};
同上
class D:public B,public C{};
D为8,如果编译器不优化A中的char就会有1(A)+8(B)+8(C)-4(B对A虚继承)-4(C对A虚继承)+3(对齐)=12bytes
class E
{
int i;
};
很明显4bytes
class F
{
double d;
};
很明显8bytes
class G
{
double num;
char in;
};
8bytes对齐,所以是8(double)+4(int)+4(对齐)=16
class H
{
int num;
double in;
};
同上
class I
{
int num;
double in;
public:
virtual ~I(){};
};
8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24
class J
{
double num;
int in;
public:
virtual ~J(){};
};
同上8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24
class K
{
int i;
int k;
public:
virtual ~K(){};
};
4(int)+4(int)+4(vptr)=12
class L
{
int i;
int j;
L(){};
public:
float ll(int i)
{
return 0.0;
}
static int hhh(int i)
{
return 0.0;
}
virtual ~L(){};
virtual ji(){};
};
虚函数表的指针vptr,只有类中出现虚函数才会出现,它指向虚函数表,所有虚函数的地址存放在此表中。4(int)+4(int)+4(vptr)=12从中看出,不管有多少虚函数,大小不变,因为类中只保存虚函数表。不管成员函数有多少,类大小也不变,因为他们不保存在对象中,无论是否是静态。
#include <iostream>
using std::cout;
using std::endl;
class A{};
class B:public virtual A{};
class C:public virtual A{};
class D:public B,public C{};
class E
{
int i;
};
class F
{
double d;
};
class G
{
double num;
char in;
};
class H
{
int num;
double in;
};
class I
{
int num;
double in;
public:
virtual ~I(){};
};
class J
{
double num;
int in;
public:
virtual ~J(){};
};
class K
{
int i;
int k;
public:
virtual ~K(){};
};
class L
{
int i;
int j;
L(){};
public:
float ll(int i)
{
return 0.0;
}
static double hhh(int i)
{
return 0.0;
}
virtual ~L(){};
virtual void ji(){};
};
int main()
{
cout <<"A "<<sizeof(A)<<endl;
cout <<"B "<<sizeof(B)<<endl;
cout <<"C "<<sizeof(C)<<endl;
cout <<"D "<<sizeof(D)<<endl;
cout <<"E "<<sizeof(E)<<endl;
cout <<"F "<<sizeof(F)<<endl;
cout <<"G "<<sizeof(G)<<endl;
cout <<"H "<<sizeof(H)<<endl;
cout <<"I "<<sizeof(I)<<endl;
cout <<"J "<<sizeof(J)<<endl;
cout <<"K "<<sizeof(K)<<endl;
cout <<"L "<<sizeof(L)<<endl;
}
/*******************************************************************/
输出结果为:
A 1
B 4
C 4
D 8
E 4
F 8
G 16
H 16
I 24
J 24
K 12
L 12
/*******************************************************************/
参考资料:
《深度探索 C++对象模型》P83~88
http://blog.csdn.net/zzm7000/archive/2006/03/30/644467.aspx