1.1 C++(www.cppentry.com)对象模式(The C++(www.cppentry.com) Object Model)(2)
图1.3说明C++(www.cppentry.com)对象模型如何应用于前面所说的Point class身上。这个模型的主要优点在于它的空间和存取时间的效率;主要缺点则是,如果应用程序代码本身未曾改变,但所用到的class objects的nonstatic data members有所修改(可能是增加、移除或更改),那么那些应用程序代码同样得重新编译。关于此点,前述的双表格模型就提供了较大的弹性,因为它多提供了一层间接性,不过它也因此付出了空间和执行效率两方面的代价。
|
| (点击查看大图)图1.3 C++(www.cppentry.com)对象模型(C++(www.cppentry.com) Object Model) |
加上继承(Adding Inheritance)
C++(www.cppentry.com)支持单一继承:
- class Library_materials { ... };
- class Book : public Library_materials { ... };
- class Rental_book : public Book { ... };
- C++(www.cppentry.com)也支持多重继承:
- // 原本的(更早于标准版的)iostream实现方式
- class iostream:
- public istream,
- public ostream { ... };
甚至,继承关系也可以指定为虚拟(virtual,也就是共享的意思):- class istream : virtual public ios { ... };
- class ostream : virtual public ios { ... };
在虚拟继承的情况下,base class不管在继承串链中被派生(derived)多少次,永远只会存在一个实例(称为subobject)。例如iostream之中就只有virtual ios base class的一个实例。
一个derived class如何在本质上模塑其base class的实例呢?在"简单对象模型"中,每一个base class可以被derived class object内的一个slot指出,该slot内含base class subobject的地址。这个体制的主要缺点是,因为间接性而导致的空间和存取时间上的额外负担,优点则是class object的大小不会因其base classes的改变而受到影响。
当然啦,你也可以想象另一种所谓的base table模型。这里所说的base class table被产生出来时,表格中的每一个slot内含一个相关的base class地址,这很像virtual table内含每一个virtual function的地址一样。每一个class object内含一个bptr,它会被初始化,指向其base class table。这种策略的主要缺点是由于间接性而导致的空间和存取时间上的额外负担,优点则是在每一个class object中对于继承都有一致的表现方式:每一个class object都应该在某个固定位置上安放一个base table指针,与base classes的大小或个数无关。第二个优点是,无须改变class objects本身,就可以放大、缩小,或更改base class table。
译注:我以下图表现base class table模型在虚拟多重继承中的应用(以稍早的iostream为例):
不管上述哪一种体制,"间接性"的级数将因为继承的深度而增加。例如,一个Rental_book需要两次间接存取才能够探取到继承自Library_materials的members,而Book只需要一次。如果在derived class内复制一个指针,指向继承串链中的每一个base class,倒是可以获得一个永远不变的存取时间。当然这必须付出代价,因为需要额外的空间来放置额外的指针。
C++(www.cppentry.com)最初采用的继承模型并不运用任何间接性:base class subobject的data members被直接放置于derived class object中。这提供了对base class members最紧凑而且最有效率的存取。缺点呢?当然就是:base class members的任何改变,包括增加、移除或改变类型等等,都使得所有用到"此base class或其derived class之objects"者必须重新编译。
自C++(www.cppentry.com) 2.0起才新导入的virtual base class,需要一些间接的base class表现方法。Virtual base class的原始模型是在class object中为每一个有关联的virtual base class加上一个指针。其他演化出来的模型则要不是导入一个virtual base class table,就是扩充原已存在的virtual table,以便维护每一个virtual base class的位置。3.4节有这方面的详细讨论。
对象模型如何影响程序(How the Object Model Effects Programs)
这对程序员带来什么意义呢?喔,不同的对象模型,会导致"现有的程序代码必须修改"以及"必须加入新的程序代码"两个结果。例如下面这个函数,其中class X 定义了一个copy constructor、一个virtual destructor和一个virtual function foo:
- X foobar()
- {
- X xx;
- X *px = new X;
-
- // foo() 是一个 virtual function
- xx.foo();
- px->foo();
-
- delete px;
- return xx;
- };