c++对象模型中提到:需要多少内存才能够表现一个class object?一般而言要有:
1 其nonstatic data members的总和大小;
2 加上热河由于alignment的需求而填补上去的空间(在32位计算机上,通常alignment为4bytes(32位),使得bus的运输量达到最高效率)
3 加上为了支持virtual而由内部产生的任何额外负担。
举例1:
class ZooAnimal {
public:
ZooAnimal();
virtual ~ZooAnimal();
..
virtual void rotate();
protected:
int loc;
string name;
};
声明ZooAnimal za("zoey")之后,对象在堆中的布局应该是
int loc(4个字节)+string name(8个字节,一个4字节的字符指针和一个用来表示长度的整数)+vptr(4个字节,指向virtual table的地址)=16字节!!
对于上面的例子,如果去除类中定义的virtual function(即去除 virtual ~ZooAnimal()和 virtual void rotate()两个虚函数),那么所占内存变为了12字节(没有了vptr)。
注意:虚函数的存在导致了vptr, 如果没有虚函数,那么也就没有vptr了。
当然,如果类虚继承自另外一个类,那么也会有4个字节的额外负担,指向virtual base class subobject的地址。
举例2:
class zooanimal
{
}
声明一个空类,调用命令
zooanimal z;
sizeof(z)输出1个字节,不是0. 这个char字节是被编译器自动安插进去的,目的使得这个class的两个objects得以在内存中配置独一无二的地址。这样 zooanimal y,z.
&y != &z;
举例3:
class concrete1{
public:
//....
private:
int val;
char bit1;
};
显然concrete1对象的大小为 4字节(int)+1个字节(char bit1)+ padding(3个字节)=8个字节!
然而:
class concrete2: public concrete1{
public:
//....
private:
char bit2;
}
注意此时concrete2对象的大小不是 4字节(int)+1个字节(char bit1)+1字节(char bit2)+padding(2个字节)=8个字节
而是8个字节(concrete1的大小)+1个字节(char bit2)+padding(3个字节)=12个字节;
同理
class concrete3: public concrete2{
public:
//....
private:
char bit3;
}
大小为 16个字节!!!这样浪费空间的目的是为了避免出现concrete1对象向concrete2对象赋值时发生bug。