C++模块4:C++对象内存模型
在C++中有两种类的数据成员:static和nonstatic,以及三种类的成员函数:static、nonstatic和virtual。在C++对象模型中,非静态数据成员被配置于每一个类的对象之中,静态数据成员则被存放在所有的类对象之外;静态及非静态成员函数也被放在类对象之外,虚函数则通过以下两个步骤支持:
A:每一个类产生出一堆指向虚函数的指针,放在表格之中,这个表格被称为虚函数表(virtual table, vtbl)。
B:每一个类对象被添加了一个指针,指向相关的虚函数表,通常这个指针被称为vptr。vptr的设定和重置都由每一个类的构造函数、析构函数和拷贝赋值运算符自动完成。另外,虚函数表地址的前面设置了一个指向type_info的指针,RTTI(Run Time Type Identification)运行时类型识别是由编译器在编译器生成的特殊类型信息,包括对象继承关系,对象本身的描述,RTTI是为多态而生成的信息,所以只有具有虚函数的对象在会生成。
1 .继承下的对象内存模型:
C++支持单一继承、多重继承和虚继承。在虚继承的情况下,虚基类不管在继承链中被派生多少次,永远只会存在一个实体。
单一继承,继承关系为class Derived : public Base。其对象的内存布局为:虚函数表指针、Base类的非static成员变量、Derived类的非static成员变量。
多重继承,继承关系为class Derived : public Base1, public Base2。其对象的内存布局为:基类Base1子对象和基类Base2子对象及Derived类的非static成员变量组成。基类子对象包括其虚函数表指针和其非static的成员变量。
重复继承,继承关系如下。Derived类的对象的内存布局与多继承相似,但是可以看到基类Base的子对象在Derived类的对象的内存中存在一份拷贝。这样直接使用Derived中基类Base的相关成员时,就会引发歧义,可使用多重虚拟继承消除之。
class Base1 : public Base
class Base2: public Base
class Derived : public Base1, public Base2
虚继承,继承关系如下。其对象的内存布局与重复继承的类的对象的内存分布类似,但是基类Base的子对象没有拷贝一份,在对象的内存中仅存在在一个Base类的子对象。但是它的非static成员变量放置在对象的末尾处。
class Base1 : virtual public Base
class Base2: virtual public Base
class Derived : public Base1, public Base2