再复杂的系统,在设计之处,总是很简单的。C++编译器的实现也是如此。
Lippman的第一个模型十分简单。 是为了尽可能降低C++编译器的设计复杂度而开发出来的,赔上的则是空间和执行期效率。
简单模型中, members本身并不放在object之中,只有指向member的指针才放在object内部。这么做可以避免对象有不同类型,而需要不同存储空间的问题。 Object中的members是以slot索引值来寻址的。 在这种对象模型中,class object的大小很容易计算出来。指针大小乘以members数目就可以了。 虽然这个模型没有被用到实际产品中去,但是关于索引或slot数目的观念,倒是被应用到C++"指向成员的指针"观念之中。
表格驱动的对象模型。
每个类对应于两张表 data member table和member function table。
data member table 中直接放数据,member function table则存放slot,这些slot在指向funtion。
这个模型也没有实际应用到真正的C++编译器上,而member function table这个观念则成为 virtual function的一个有效方案。 virtual function还有其他什么实现方案吗? 各个编译器会采用不同的实现方案吗? data member最后的实现,不是用 表进行组织的吗?
C++对象模型。
Stroustrup当初设计C++对象模型是从简单对象模型派生而来的,并对内存空间和存取时间做了优化。
Nonstatic data members被配置在每一个 class object之内,static data members 则被存放在所有的class object 之外。
new出来的对象放在堆中,而普通的变量这是放在栈中(函数调用时候的栈)。 对此的理解好像有更深入了一些。
每个class有一个 virtual table vtbl,里面存放着一堆指向 member function的指针。 每个class object被添加了一个指针,指向相关的 virtual table,通常这个指针被称为 vptr。 vptr的设置和重置,由类的 constructor, distructor和copy assignment运算符自动完成。 (具体在第五章讨论?)
每个class关联的type_info_object 也放在 virtual table中, 用来支持运行时类型识别 runtime type identification, RTTI, 通常放在virtual table的第一个slot处
这个模型和表格驱动模型稍微有点区别, 表格驱动模型, 数据成员也是通过一张表进行查找的,而这里的C++对象模型,则直接把数据放到了对象之中。
这种设计的缺点是,数据成员修改(添加、删除或修改数据成员),程序代码也需要重新编译。而通过两张表的话,程序代码是不用重新编译的。
(还要和之前的代码进行比对,看是否修改了函数?呵呵,一修改就重新编译,显得更简单吧。) 还有用两张表,多了一层间接性,有更大弹性,但是需要付出空间和执行效率两方面的代价。
加入继承后的考虑:
C++对象模型的继承机制,原来不运用任何间接性。 这样可以对base class member进行最紧凑而且有效的存取。 缺点是, base class的任何改变,都会导致 base class和derived class的重新编译。 ---> 使用间接机制呢? 有时应该也需要重新编译子类的吧,如子类用到一个父类的方法,而父类中这个方法已经被删除。。。 如果仅仅是修改内部,可能子类不需要重新编译,只需要重新连接就可以了。
posted on 2009-09-03 21:30
thinke365 阅读(123)
评论(0) 编辑 收藏 引用 所属分类:
object model