现在的位置: 首页 > 综合 > 正文

C++多态实现机制

2013年05月11日 ⁄ 综合 ⁄ 共 893字 ⁄ 字号 评论关闭

C++中多态可以分为基于继承和虚函数的动态多态以及基于模板的静态多态。

对于静态多态,C++编译器在编译时,根据不同的函数调用,实例化相应的函数模板,产生特定的函数,从而实现了静态多态。

那么动态多态的是怎样实现的?先了解两个概念:静态绑定和动态绑定

 
1、静态绑定(static bingding),也叫早期绑定,简单来说就是编译器在编译期间就明确知道所要调用的方法,并将该方法的地址赋给了Call指令的funcaddr。因此,运行期间直接使用Call指令就可调用到相应的方法。

2、动态绑定(dynamic binding),也叫晚期绑定,与静态绑定不同,在编译期间,编译器并不能明确知道究竟要调用的是哪一个方法,而这,要知道运行期间使用的具体是哪个对象才能决定。

好了,有了这两个概念以后,我们就可以说,虚函数声明关键字virtual的作用就是告诉编译器:我要进行动态绑定!编译器当然会尊重你的意见,而且为了完成你这个要求,编译器还要做很多的事情:编译器自动在声明了virtual方法的类中插入一个指针vptr和一个数据结构VTable(vptr用以指向VTable;VTable是一个指针数组,里面存放着函数的地址)。
    1、VTable中只能存放声明为virtual的方法,其它方法不能存放在里面。由于纯虚函数没有函数体,因此该位置中并不存放相应函数的地址,而是可以选择存放一个出错处理的函数的地址,当该位置被意外调用时,可以用出错函数进行相应的处理。
    2、派生类的VTalbe中记录的从基类中继承下来的虚函数地址的索引号必须跟该虚函数在基类VTable中的索引号保持一致。
    3、vptr是由编译器自动插入生成的,因此编译器必须负责为其进行初始化。初始化的时间选在对象创建时,而地点就在构造函数中。因此,编译器必须保证每个类至少有一个构造函数,若没有,自动为其生成一个默认构造函数。
     4、vptr通常放在对象的起始处,也就是Addr(obj) == Addr(obj.vptr)。‘

有了vptr和VTable,当一个类调用某个函数时,通过查表得到函数的入口地址,从而实现多态。


抱歉!评论已关闭.