读书笔记 《深度探索c++对象模型》 (3)

第四章:Function语意学
4.2 虚拟成员函数
a) 单一继承下的virtual function
    一个class只会有一个virtual table。每一个table内含其对应的class object的所有active virtual functions的函数实体地址。包括:

   这个class自己定义的virtual function,它override了一个可能存在的base class virtual function函数实体。
   继承自base class的函数实体。
   一个纯虚函数实体。

b) 多重继承下的virtual function
   在多重继承中实现virtual functions。其复杂度在于第二个以及之后的base class身上。例如: 有如上派生关系,如果有: 那么第一行会将pbase指针调整以指向Base2 subobject。否则的话,类似 这种非多态应用都会失败。而在第三行的时候,由于要调用Derived的析构,所以this指针又会被调整到Derived对象开头。
其实现是运用了一种叫Thunk的技术,在代码里面插了一小段汇编代码,用来做两件事情:调整this指针的位置,跳转到virtual function的位置。
于是,对于多重继承来说,有多少个base class,就有多少个vptr,分别指向多少张virtual table。每个virtual table的内容参见《深度探索c++对象模型》P165页的图。注意,由于base_1和derived class共享一个virtual table,所以该virtual table内的内容最多。甚至包括了Base_2::mumble。不过Base_2::mumble的真正地址存放在Base_2对应的virtual table中。所以想要通过derived class的指针条用mumble方法,需要利用thunk调整this指针,这就是下面三种情况的第2种。(注意,某base class的指针,new出来的对象是derived的,也不能调用其他base class的方法指针的类型是什么,就使用那个基类相应的virtua table。派生类和第一个base class使用的是同一个virtual table。
有三种情况,第二或者后继的base class会影响到virtual functions的支持。这时候需要利用thunk调整this指针。
c) 虚拟继承下的virtual functions 由于Point2d和Point3d的起始位置不一样,所以两者之间的转换也需要做this指针调整。所以对于Point3d object来说(编译器是VC),有两张virtual table,一个是继承下来的,里面内容z()和析构函数变成了derived class的z()和析构。mumble()应该保持不变。另一长virtual table里面多了一个virtual base class object的offset,其余一样。(见《深度探索c++对象模型》P169页的图)
不过有些编译器如GCC则是将这个offset加到第一张table中,于是GCC编译器编译的结果也只有一张virtual table。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值