快速业务通道

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

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-30
d int (*)();

static member function经常被用作回调(callback)函数。

***虚拟成员函数(Virtual Member Functions)***

对于像ptr->z()的调用操作将 需要ptr在执行期的某些相关信息,为了使得其能在执行期顺利高效地找到并调用z()的适当实体,我 们考虑往对象中添加一些额外信息。

(1)一个字符串或数字,表示class的类型;

(2) 一个指针,指向某表格,表格中带有程序的virtual functions的执行期地址;

在C++中, virtual functions可在编译时期获知,由于程序执行时,表格的大小和内容都不会改变,所以该表格的 建构和存取皆可由编译器完全掌握,不需要执行期的任何介入。

(3)为了找到表格,每一个 class object被安插上一个由编译器内部产生的指针,指向该表格;

(4)为了找到函数地址, 每一个virtual function被指派一个表格索引值。

一个class只会有一个virtual table,其中内 含其对应的class object中所有active virtual functions函数实体的地址,具体包括:

(a) 这个class所定义的函数实体

它会改写一个可能存在的base class virtual function函数实体。 若base class中不存在相应的函数,则会在derived class的virtual table增加相应的slot.

(b )继承自base class的函数实体

这是在derived class决定不改写virtual function时才会出现 的情况。具体来说,base class中的函数实体的地址会被拷贝到derived class的virtual table相对应 的slot之中。

(c)pure_virtual_called函数实体

对于这样的式子:

ptr ->z();

运用了上述手法后,虽然我不知道哪一个z()函数实体会被调用,但却知道 每一个z()函数都被放在slot 4(这里假设base class中z()是第四个声明的virtual function)。

// 内部转化为
(*ptr->vptr[4])(ptr);

***多重继承下的 Virtual Functions***

在多重继承中支持virtual functions,其复杂度围绕在第二个及后继的 base classes身上,以及“必须在执行期调整this指针”这一点。

多重继承到来的问题:

(1)经由指向“第二或后继之base class”的指针(或reference)来调用 derived class virtual function,该调用操作连带的“必要的this指针调整”操作,必须 在执行期完成;

以下面的继承体系为例:

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;

会被 内部转化为:

// 转移以支持第二个base class
Derived *temp = new Derived;
Base2 *pbase2 = temp ? temp + sizeof(Base1) : 0;

如果没有这样的调整,指针的 任何“非多态运用”都将失败:

pbase2->data_Base2;

当程 序员要删除pbase2所指的对象时:

// 必须调用正确的virtual destructor函数实体
// pbase2需要调整,以指出完整对象的起始点
delete pbase2;

指针必须被再一 次调整,以求再一次指向Derived对象的起始处。然而上述的offset加法却不能够在编译时期直接设定, 因为pbase2所指的真正对象只有在执行期才能确定。

自此,我们明白了在多重继承下所面临的独 特问题:经由指向“第二或后继之base class”的指针(或reference)来调用derived class virtual function,该调用操作所连带的&ldqu

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号