前言
对象模型是深层结构知识,关系到“与语言无关、与平台无关、跨网络可执行”软件组件的基础。
C++相对于精瘦的C来说,多了许多特性,正因如此,我们更有必要去探索、了解C++对象模型,到底背着我们又发生了什么事情。在了解C++对象模型之前,有必要先从简单一点的两个模型入手:简单对象模型、表格驱动模型。
简单对象模型
现在我们考虑一个Point类,其声明如下:
class Point {
public:
Point(float xval);
virtual ~Point();
float x() const;
static int PointCount();
protected:
virtual ostream& print(ostream& os) const;
float _x;
static int _point_count;
};
在C++中,成员数据(class data member)有两种:static和nonstatic,成员函数(class member function)有三种:static、nonstatic和virtual。
那么上述的Point类,用简单对象模型应该怎么塑模这些data members和function members呢,如下:
这个对象模型比较简单,在这个简单模型中,object中存放的并不是member而是一系列的slots,每个slot指向一个member,按member在class中的声明顺序,即object中存放的是“指向member的指针”,这就避免了因不同类型的member需要不同存储空间所带来的问题。
表格驱动模型
与简单对象模型类似,但又有所不同。表格驱动对象模型将class中的member分成data和function两个部分,一个放在data member table中,一个放在member function table中,而class object则持有指向这两个table的指针。在往下划分,data member table直接存放data本身,而member function table则是一系列的slots,每个slot指向一个member function,如下。
这种对象模型不会因class中data member和member function的增减而改变其大小,但在操作member function时,比data member多了一次寻址。
CPlusPlus对象模型
C++对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。在此模型中对data而言nonstatic data member被置于class object之内,static data member被置于class object之外;对function而言,static和nonstatic member function被置于class object之外,virtual member function则由以下两步支持:
1、每一个class产生出一堆指向virtual function的指针,并存放于表格中,即virtual table(vtbl);
2、每个class object被安插一个指针(vptr),指向相关的virtual table。
上面两点是用以支持virtual function的。在C++中,关键字virtual的存在只有两处,一出现在member function之前形成virtual function,二出现在inheritance时形成virtual inheritance(虚拟继承),若base class或derived class不是以上两种情况,也无virtual table之说了。如下。
另外,在C++对象模型中我们可以看到vptr指向的virtual table中多了一个type_info,并且位于vtbl的第一个slot,这是用以支持rumtime type identification(RTTI)的,这个后面的学习笔记再说。vptr这个指针的设定、重置都由每一个class的constructor、destructor和copy assignment运算符自动完成。
更进一步的说,pt->vtbl[0]指向Point的type_info object,pt->vtbl[1]指向Point::~Point(),pt->vtbl[2]指向Point::print()。
参考资料:
[1] 深度探索C++对象模型,[美]Stanley B. Lippman著,侯捷译;
[2] C++对象模型,吴秦(http://www.cnblogs.com/skynet/)