简单对象模型
这个模型十分简单,一个object由许多的slots组成,每一个slot指向一个member,member按照声明的顺序指定一个slot。object实际存储的是指向对象的指针。
C++对象模型
在C++的实现中,非静态数据成员被存储在每一个类对象中,静态数据成员被存储在类对象之外。成员函数也被存储在对象之外。而对于虚函数,有如下的处理方式:每一个class产生一系列指向虚函数的指针,放置在一个称为虚函数表的表格中。每一个类对象都被安插一个指针,指向对应的vtable。这个指针被称为vptr。vptr的设置和重置由每一个class的构造函数、析构函数和复制构造函数等自动完成。每一个class关联的type_info object也由vtable指出,放在表格的第一个slot.
对于继承,在目前的实现中,派生类的成员被直接放置在各个基类的成员之后,各个基类按照继承时声明的顺序放置。具体的模型在3.4节中将会被详细讨论。
class 和 struct 的差异
在C语言中,struct 被用来声明一个结构体,这个结构体中的各个成员按照声明的顺序被放置在内存中,此外可能会有padding。而在C++中,class和struct几乎可以认为是同一种东西:class默认的成员是私有的,而struct的成员则默认是公有的。
有的C程序员习惯在一个结构体的末尾放置一个仅有一个元素的数组来使每个结构体变量拥有可变大小的数组。但是,在C++中,这不一定行得通。可以保证,在同一个访问控制符的控制域中,成员都是按照声明的顺序放置的。但是不同的访问控制符之间的成员的顺序(即使访问权限相同)可能不会按照排列的顺序来安排。同时,C++的class中具有的虚函数等也会导致这个技巧失效。
对于想要在C++中使用C struct的情况,最好的方式是将C struct单独声明,并将C struct对象作为一个class的成员变量。这样可以保证这个C struct与C语言兼容。如果使用继承的方式,那么C++编译器将可能会插入一些其他数据,破坏兼容性。
C++的多态
在C++中,多态可以通过以下的几种方式来达成:
- 通过一个指向派生类对象的基类指针
- 通过dynamic_cast和typeid运算符
- 通过虚函数