当前位置:C++技术网 > 资讯 > 虚函数学习之虚函数详解

虚函数学习之虚函数详解

更新时间:2015-11-20 23:43:17浏览次数:1+次

把函数体与函数调用相联系称为捆绑。当捆绑在程序运行之前完成时,这称为早捆绑。晚捆绑就是根据对象的类型,发生在运行时。。当一个语言实现晚捆绑时,必须有某种机制
来确定运行时对象的类型并调用合适的成员函数。对于特定的函数,为了引起晚捆绑,C++要求在基类中使用virtual关键字。晚捆绑只对virtual函数起作用。而且只在使用含有virtual
函数的基类的地址时发生。

为了创建像virtual这样的函数,可以简单地在这个函数声明的前面加上关键字virtual,仅仅在声明时需要使用关键字virtual,定义时不需要.

针对brass和woodwind,adjust()函数没有重写。当出现这种情况时,将会自动调用继承层次中"最近"的定义。晚捆绑如何发生?所有的工作都在幕后完成。
当告诉编译器要晚捆绑时(通过virtual),编译器安装必要的晚捆绑机制。这个意味着,如果对brash对象通过基类instrument地址调用play(),将得到恰当的函数。
为了达到这个目的,编译器对每个包含有虚函数的类创建一个表(VTABLE),在VTABLE中,编译器放置特定类的虚函数的地址。在每个带有虚函数的类中,编译器秘密的放置
一个指针,称为vpointer,指向这个对象的VTABLE。当通过积累指针做虚函数调用时,编译器静态的插入能去的这个VTABLE(虚表)并在虚表中查找函数地址的代码。
举一个例子以便测量虚函数的类的长度。

不带虚函数,对象的长度恰好就是所期望的长度:int的长度。而带有单个虚函数的类,其长度是不带虚函数的类的长度就上一个void指针的长度,它反映出,如果有一个或
或多个虚函数,编译器都只在这个结构中插入一个指针。


虚函数功能表:

这个instrument指针数组没有特殊的类型信息。他的每一个元素都指向一个类型为instrument的对象。wind,percussion,brass都可以归入这个类型之中,因为它
们都是从instrument派生来的。每当创建一个包含有组函数的类或从包含有虚函数的类派生一个类时,编译器就为这个类创建一个唯一的VTABLE。如上图的右面所示
在这个表中,编译器放置了在这个类中或他的基类中所有以声明为virtual的函数的地址。如果在这个派生类中没有对在基类中声明为virtual的函数进行重新定义,编译器就使用基类的这个虚函数
地址(在brass的VTABLE中,adjust的入口就是这种情况)然后编译器在这个类中放置VPTR。当使用简单继承时,对于每个对象只有一个VPTR。VPTR必须初始化为指向相应
的VTABLE的起始地址
一旦VPTR被初始化为为指向相应的VTABLE,对象就知道自己是什么类型但只有虚函数被调用时才有用。
代码摘自《C++编程思想》----书籍本网站提供下载