1、单继承的对象布局
(1) 在普通继承(没有虚函数、没有继承虚基类)的情况下,按父对象、子对象的顺序布局
我们来看下面的例子:
class Base {
protected:
int x;
int y;
};
class Derive : public Base {
private:
int z;
};
int main()
{
Derive d;
return 0;
}
在《C++对象模型(1)-- 对象模型概述》这篇文章中,我讲了验证对象模型的3种方法。我这里用cl /d1命令查看对象布局。
这时的对象布局是这样的:
(2) sub object的原样完整性
当把一个大的object赋给一个小的object时,会引起object切割:将大object的sub object赋值给小的object,也就是说sub object必须保持其完整原样性。
我们通过一个例子来详细地解释下这个问题。
class Base {
protected:
int x;
short y;
};
class Derive : public Base{
private:
short z;
};
这个时候,Base的对象布局是这样的:
Derive的对象布局是怎样的?
为什么是右边的布局而不是左边这样的布局呢?
出现在derive class中的base class,其sub object必须保持其完整原样性。
比如下面这个例子:
Base *pb1, *pb2;
pb1 = new Base();
pb2 = new Derive();
*pb1 = *pb2;
当把大的Derive类对象赋给小的Base类对象时,Base类对象必须保证其完整性。
2、多继承的对象布局
跟单继承类似,在普通继承(没有虚函数、没有继承虚基类)的情况下,按父对象、子对象的顺序布局。
class X {
public:
int x_i;
};
class Y {
public:
int y_i;
};
class Z : public X, public Y {
public:
int z_i;
};
int main()
{
Z z;
return 0;
}
3、多重继承的对象布局
class W {
public:
int w_i;
};
class X : public W{
public:
int x_i;
};
class Y : public W{
public:
int y_i;
};
class Z : public X, public Y {
public:
int z_i;
};
int main()
{
Z z;
return 0;
}
这时,类Z的爷爷类W会被继承2次,一次是X::W,另一次是Y::W,所以sizeof(z) = 5 * 4 = 20。