C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)

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命令查看对象布局。

C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)_第1张图片

这时的对象布局是这样的:

C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)_第2张图片

(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的对象布局是这样的:

C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)_第3张图片

Derive的对象布局是怎样的?

C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)_第4张图片

为什么是右边的布局而不是左边这样的布局呢?

出现在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;
}

C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)_第5张图片

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。

C++对象模型(5)-- 数据语义学:继承的对象布局(不含虚函数)_第6张图片

你可能感兴趣的:(C++对象模型,c++,对象模型,继承)