读书笔记 《深度探索c++对象模型》 (3)
2010-07-03 04:22
267 查看
第四章: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身上。例如:
其实现是运用了一种叫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
不过有些编译器如GCC则是将这个offset加到第一张table中,于是GCC编译器编译的结果也只有一张virtual table。
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身上。例如:
class Base1 { public: Base1(); virtual ~Base1(); virtual void SpeakClearly(); virtual Base1* clone() const; protected: float data_Base1; }; class Base2 { public: Base2(); virtual ~Base2(); virtual void mumble(); virtual Base2* clone() const; protected: float data_Base2; }; class Derived : public Base1, public Base2 { public: Derived(); virtual ~Derived(); virtual Derived* clone() const; protected: float data_Derived; };有如上派生关系,如果有:
Base2 *pbase2 = new Derived; delete pbase2;那么第一行会将pbase指针调整以指向Base2 subobject。否则的话,类似
pbase2->data_Base2;这种非多态应用都会失败。而在第三行的时候,由于要调用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指针。
// 情况1,通过一个指向第二个base class的指针调用一个derived class virtual function Base2 *pbase2 = new Derived; // 调用~Derived(), pbase2 必须向后调整sizeof(Base1)个字节 delete pbase2; // 情况2,通过一个指向Derived class的指针调用一个继承自第二个base class的virtual function Derived *pderived = new Derived; // pderived必须向前调整sizeof(Base1)个字节 pderived->mumble(); // 情况3,先向后调整sizeof(Base1)个字节 Base2 *pbase21 = new Derived; // 调用clone方法时,pbase21调整到Derived对象开头,于是clone的Derived版本会被调用,它会返回一个Derived的指针,然后再被向后调整到指向Base2 SubObject Base2 *pbase22 = pbase21->clone();
c) 虚拟继承下的virtual functions
class Point2d { public: Point2d(); virtual ~Point2d(); virtual void mumble(); virtual float z(); protected: float _x, _y; }; class Point3d : public virtual Point2d { public: Point3d(); ~Point3d(); float z(); protected: float _z; };由于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。
相关文章推荐
- 《深度探索C++对象模型》读书笔记(一)
- 《深度探索C++对象模型》读书笔记之Function语意学
- 《深度探索C++对象模型》读书笔记(5)
- 《深度探索C++对象模型》读书笔记(4)
- 《深度探索C++对象模型》读书笔记第四章:Function语意学
- [C++]《深度探索C++对象模型》读书笔记 - nontrivial default constructor
- 《深度探索C++对象模型》读书笔记2
- 《深度探索C++对象模型》读书笔记之构造、析构、拷贝语意学
- 读书笔记 《深度探索c++对象模型》 (1)
- 读书笔记 《深度探索c++对象模型》 (2)
- 《深度探索C++对象模型》读书笔记(4)
- 读书笔记《深度探索c++对象模型》 概述
- 《深度探索C++对象模型》读书笔记3
- 《深度探索C++对象模型》读书笔记(6)
- 《深度探索c++对象模型》读书笔记(一)
- 《深度探索C++对象模型》读书笔记(5)
- 深度探索C++对象模型》读书笔记(2)
- 《深度探索C++对象模型》读书笔记之关于对象
- 《深度探索C++对象模型》读书笔记
- 《深度探索C++对象模型》读书笔记——Function 语意学【for_wind】