上一节讲了C++基本对象(没有使用继承)的模型构造。本节介绍C++的继承模型。
C++支持单一继承。
class Library_materials {...};
class Book:public Library_materials {...};
class Rental_book: public Book {...};
C++也支持多重继承。
class iostream:
public istream,
public ostream {...};
同时,继承关系也可以指定为虚拟(virtual,也就是共享的意思);
class istream : virtual public ios {...};
class ostream :virtual public ios {...};
在虚拟继承的情况下,base class不管在继承串链中被派生多少次,永远只会存在一个实体,例如上面的iostream之中就只有virtual ios base class的一个实体。
那么如果构造这种继承模型呢?(即一个derived class 如何在本质上模塑其base class的实体)
在“简单对象模型”中,每一个base class可以被derived class object内的一个slot指出,该slot内含base class subobject的地址。
优点:class object的大小不会因其base classes的改变而受到影响(因为derived class object只含有指向base class subobject的指针,无论base class subobject 如何改变,derived class object 不用改变)
缺点: 因为间接性而导致空间和存取时间上的额外负担。
另一种为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。
不管上述哪一种体制,“间接性”的级数都将因为继承的深度而增加。(想想多级继承,沿着继承串链从derived class 到 base class)
如果在derived class内复制多个指针,每一个指针指向继承串链中的一个base class,这样可以获得一个永远不变的存取时间。但是这必须要付出代价,因为需要额外的空间来放置额外的指针。
C++最初采用的继承模型并不运用任何间接性:base class subobject 的data members被直接放置于derived class object中。这提供了对base class members最紧凑而且最有效率的存取。
缺点:base class members 的任何改变,包括增加、移除或改变类型等,都使得所有用到“此base class或其derived class之objects”者必须重新编译。
C++ 2.0起才新导入 Virtual base class,需要一些间接的base class表现方法。Virutal base class的原始模型是在class object 中为每一个有关联的virtual base class加上一个指针。其它演化出来的模型则若不是导入一个virtual base class table,就是扩充原以存在的virtual table,以便维护每一个virtual base class的位置。