一、什么是对象模型
- 语言中直接支持面向对象程序设计的部分
- 对于各种支持的底层实现机制
C与C++的区别,C语言中是将“数据”和“处理数据的操作(函数)”分离开来的,语言本身没有支持“数据和函数”之间的关联性,但是在C++中,却提供了一种ADT(abstract data type),它将“数据”和“ 处理数据的操作(函数)”结合起来,加入了class关键字。
考虑C++加上封装之后是否会产生布局成本,答案是:否!实际上,在C++中class就像C的struct的情况一样,member functions虽然含在class声明之内,却不出现在object之中,每一个non_inline member function只会诞生一个函数实体。至于每一个“拥有零个或一个定义”的inline function则会在其每一个使用者身上产生一个函数实体。这一个并未带给它任何空间或执行期的不良回应。C++在布局以及存取时间上主要的额外负担是由virtual引起,包括:virtual function机制、vitrtual base class。
二、C++的三种对象模型
C++是面向对象的语言,类是C++与C的区别。在C++中,有两种class data members:static和nonstatic,以及三种class member function:static、nonstatic和virtual。已知有下面这个class Point声明:
class Point
{
public:
Point(float x);
virtual ~Point();
float x() const;
static int PointCount();
protected:
virtual ostream& print(ostream& os) const;
float _x;
static int _point_count;
};
这个类的对象模型是怎样的?
在C++的构思和草案阶段,从C++的编译器实现和其他方面考虑,曾经出现过几个对象模型,这些模型逐步的完善和改进,形成了现在我们看到的C++对象模型。
1、简单对象模型
第一个模型十分简单,也许是为了减少C++编译器的设计复杂度,代价是空间和效率的损失。在这模型中,一个object(对象)是一系列的slots(注:不知如何翻译合适),每一个slot对应一个member(data or function)。按照member的声明顺序,各被指定一个slot。如下图:
在简单对象模型中,members本身不放在object中,只有“指向member的指针”才放在object中。这么做可以避免“member有不同的类型,因而需要不同的存储空间”所带来的问题。object中的member是以slot的索引值来寻址。例如,_x的索引为6,_x的地址=pt地址+6*指针大小。并且,一个object的大小可以很容易的计算出来“指针大小乘以member的个数”。
这个模型未被应用于实际的产品,但是关于索引和slot的个数概念,倒是被应用到C++的“指向成员的指针”观念之中。
2、表格驱动模型
为了对所有的classed的所有objects都有一致的表达方式,另一种对象模型是把所有与members相关的信息抽出来,放在一个data member table和一个members function table之中。class object本身则内含指向这两个表格的指针,Member function table是一系列slot,每一个slot指出一个member function;Data member table则直接持有data本身。如下图:
虽然这个模型未应用于实际产品,但member function table这个观念却成为了支持virtual function的一个有效方案。
3、C++对象模型
C++对象模式是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。在此模型中,
-
Nonstatic data members被配置于每一个class object之内,
-
static data member则被存放在个别的class object之外(单独的一块区域:静态区)
-
static 和 nonstatic function也被放在个别的class object之外
-
virtual function 则以两个步骤支持之:
- 每一个class 产生出一堆指向virtual function的指针,放在表格之中。这个表格称之为virtual table(vtbl)
- 每一个class object 被安插一个指针,指向相关的virtual table,通常这个指针称之为vptr, vptr的设定和重置都由每一个class的constructor、destruction和copy assignment运算符自动完成。每一个class所关联的type_info object(用以支持运行时类型确定,RTTI)也经由virtual table指出,通常放在表格第一个slot。
这个模型的主要优点是它的空间和存取效率。缺点是如果应用程序本身代码未改变,但所用到的class object的nonstatic data member有所改变(增加、删除、或更改),那么应用程序的代码同样需要重新编译。而前面所提到的表格驱动模型就有较大的弹性,因为它多了一个间接层。
总结:
- C与C++的区别,是ADT。
- 三种对象模型,C++使用了第三种,是在空间和效率上找一个平衡点。