C++对象模型——关于对象(第一章)

1.1.3    C++对象模型(The C++ Object Model)    

    C++对象模型的主要优点在于它空间和存取时间的效率;主要缺点是,如果应用程序代码本身并未改变,但所用的class object的nonstatic data members有所修改(可能是增加、移除或修改),那么那些应用程序代码同样得重新编译。关于这点,前面的的表格驱动模型就提供了较大的弹性,因为它多提供了一层间接性,不过它也因此付出空间和执行效率两方面的代价。
加上继承 (Adding Inheritance)
     C++支持单一继承:
class Libarary_materials {...};
class Book : public Library_materials {...};
class Rental_book : public Book {...};
    C++也支持多重继承:
class iostream:
public istream,
public ostream {...};
    甚至,继承关系也可以指定为虚拟:
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的改变而受到影响
    另一种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.
    不管上述哪一种体制,"间接性"的级数都将因为继承的深度而增加,例如一个Rental_book需要两次间接存取才能够探取到继承自Library_materials的members,而Book只需要一次。如果在derived class内复制一个指针,指向继承串链中的每一个base class,倒是可以获得一个永远不变的存取时间。当然这必须付出代价,因为需要额外的空间来放置额外的指针。
    C++最初采用的继承模型并不运用任何间接性:base class subobject的data members被直接放置于derived class object中,这提供了对base class members最紧凑而且最有效率的存取。缺点是base clas members的任何改变,包括增减、移除或改变类型,都使得所有用到此base class或者其derived class的objects必须重新编译。
    自C++2.0起才新导入的virtual base class,需要一些间接的base class表现方法。virtual base class的原始模型是在class object中为一个有关联的virtual base class加上一个指针,其他演化出来的模型则若不是导入一个virtual base class table,就是扩充原已存在的virtual table,以便维护每一个virtual base class的位置。
对象模型如何影响程序 (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;
}
    这个函数有可能在内部被转化为:
// 可能的内部转换结果
// 虚拟C++码
void foobar(X &_result)
{
    // 构造 _result
    // _result 用来取代 local xx...
    _result.X::X();

    // 扩展 X *px = new X;
    px = _new(sizeof(X));
    if (px != 0)
        px->X::X();

    // 扩展xx.foo() 但不使用virtual机制
    // 以_result取代xx
    foo(&_result);

    // 使用virtual 机制扩展px->foo()
    (*px->vtbl[2])(px);

    // 扩展delete px;
    if (px != 0) {
        (*px->vtbl[1])(px);
        _delete(px);
    }

    // 不需使用named return statement
    // 不需要销毁local object xx
    return;
}
没有创建临时变量对象,也不需要销毁临时对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值