http://patmusing.blog.163.com/blog/static/135834960201001432110804
一个类的对象到底有多大?其大小由什么因素影响?
我们假定这个类没有继承任何其他类,且没有虚函数。先看下面例子:
#include <iostream>
using namespace std;
class Concrete
{
public:
Concrete():val(0), c1('A'), c2('B')//, c3('C')
{
}
private:
int val;
char c1;
char c2;
//char c3;
};
int main(void)
{
Concrete c;
cout << sizeof(c) << endl;
return 0;
}
运行上面的程序,不管是否有成员变量c3,输出结果均为8,为什么呢?
由于内存的alignment的原因,所有对象的大小为4bytes的整数倍(因为其数据成员的数据类型最大占用字节数为4,即sizeof(int val) = 4),不足的就填充,如下面的图示。
(有成员变量c3的情况) (没有成员变量c3的情况)
出现在derived class中的base class subobject保持其完成原样性
请看下面例子:
#include <iostream>
using namespace std;
class Concrete1
{
private:
int val;
char c1;
public:
inline Concrete1(int i, char c1) : val(i), c1(c1)
{
}
};
class Concrete2 : public Concrete1
{
private:
char c2;
public:
inline Concrete2(int i, char c1, char c2) : Concrete1(i, c1), c2(c2)
{
}
};
class Concrete3 : public Concrete2
{
private:
char c3;
public:
inline Concrete3(int i, char c1, char c2, char c3) : Concrete2(i, c1, c2), c3(c3)
{
}
};
int main(void)
{
Concrete3 c(1, 'A', 'B', 'C');
cout << sizeof(c) << endl;
return 0;
}
输出会是多少呢?类Concrete3和1)中的类Concrete完成的功能一模一样,但是Concrete3的对象的空间确变成了16bytes,比原来的整整多出一倍!原因就是C++语言保证“出现在derived class中的base class suboject有其完整性”。图解如下:
在上图中Concrete2类型的对象中,为什么也要填充3bytes呢?这还是因为继承了Concrete1的缘故。正是因为继承了Concrete1中的int val,因此Concrete2的对齐数变成了4 bytes,因此必须要填充3 bytes。总结如下:
其一,C++语言保证“出现在derived class中的base class suboject有其完整性”;
其二,derived class的对齐数 = min(指定的全局对齐数,max(base class的对齐数,derived class的对齐数))