在继承关系下,一个类的数据成员规则如下:
- 派生类的数据成员为:其自身的数据成员加上基类的数据成员的综合
- 派生类与基类的数据成员的排列次序并未在C++标准中强制规定:理论上编译器自由安排。在大部分编译器上,基类的数据成员总是先出现
- 当有虚基类时,上面的规则就会失效(具体见下面讲解)
下面我们将从“单一继承不含virtual functions”、“单一继承并含有virtual functions”、“多重继承”、“虚拟继承”等四种情况介绍对象布局模型
一、单一继承不含virtual functions(没有多态)
- 单一继承可以共享“数据本身”以及“数据的处理方法”,并将其局部化,一般而言,普通继承(相对于虚拟继承)并不会增加空间或存取时间上的额外负担
上图所示为单一继承而且没有virtual function时的数据布局,Point3d类继承了Point2d类。
单一继承可能会带来内存膨胀
- 在使用class时,可能会将一个class分解为多个class,这时可能会带来内存空间的膨胀
演示案例①
class Concrete
{
private:
int val;
char c1;
char c2;
char c3;
};
int main()
{
Concrete c;
std::cout << sizeof(c) << std::endl;
return 0;
}
- 在上面的Concrete类中,在一个32位的机器上,其大小为:val(4字节)+c1(1字节)+c2(1字节)+c3(1字节)+内存对齐补齐的1字节(padding)
演示案例② - 将上面的consrete类分解为3个类来实现
class Concrete1
{
private:
int value;
char c1;
};
class Concrete2:public Concrete1
{
private:
char c2;
};
class Concrete3:public Concrete2
{
private:
char c3;
};
int main()
{
Concrete1 c1;
Concrete2 c2;
Concrete3 c3;
std::cout << sizeof(c1) << std::endl;
std::cout << sizeof(c2) << std::endl;
std::cout << sizeof(c3) << std::endl;
return 0;
}
<