<b>C++多态技术的实现和沉思</b>[VC/C++编程]
本文“<b>C++多态技术的实现和沉思</b>[VC/C++编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
面向对象技术最早呈现于1960年代的Simula 67系统,并且在1970年代保罗阿托实行室开辟的Smalltalk系统中发展成熟.但是关于大部份程序员来说,C++是第一个可用的面向对象程序计划语言.因此,我们关于面向对象的很多概念和思惟直接来自于C++.但是,C++在实现面向对象中关键的多态性时,挑选了与Smalltalk完好差别的筹划.后来果是,固然在表面上二者都实现了类似的多态性,但是在实践中却有着宏大的辨别.具体的说,C++的多态性实现越发高效,但是并不实用于全部场所.很多经验不足的C++开辟者不懂得这个原理,在不符合的场所强行利用C++的多态性机制,落入削足适履的陷阱而不能自拔.本文将具体探究C++多态性技术的范围性及办理的办法.
两种差别虚办法调用实现技术
C++的多态性是C++实现面向对象技术的底子.具体的说,通过一个指向基类的指针调用虚成员函数的时刻,运行时系统将可以按照指针所指向的实际对象调用得当的成员函数实现.以下所示:
class Base {
public:
virtual void vmf() { ... }
};
class Derived : public Base {
public:
virtual void vmf() { ... }
};
Base* p = new Base();
p->vmf(); // 这里调用Base::vmf
p = new Derived();
p->vmf(); // 这里调用
// Derived::vmf
...
请注意代码中突出注释的两行,固然其表面语法完好相同,但是却辨别调用了差别的函数实现.所谓的“多态”即就此而言.这些知识是每一个C++开辟者都熟知的.
目前我们假定自己是语言的实现者,我们该当若何来实现这种多态性?略加考虑,我们不可贵到一个基本的思绪.多态性的实现要求我们增添一个间接层,在这个间接层中拦阻关于办法的调用,然后按照指针所指向的实际对象调用呼应的办法实现.在这个历程中我们人为增添的这个间接层非常重要,它需求完成以下几项工作:
1. 获知办法调用的全部信息,包含被调用的是哪个办法,传入的实际参数有哪些.
2. 获知调用发生时指针(引用)所指向的实际对象.
3. 按照第1、2步得到的信息,找到符合的办法实现代码,履行调用.
这里的关键在于如安在第3 步中找到符合的办法实现代码.由于多态性是就对象而言的,因此我们在计划时要把符合的办法实现代码与对象绑定到一同.也就是说,必须在对象级别实现一个查找表构造,按照1、2步得到的对象和办法信息,在这个查找表中找到实际的办法代码地址,并加以调用.目前问题变成了,我们该当按照什么信息举行办法查找.关于这个问题有两个差别的办理思绪,一个是按照名称举行查找,另一个是按照位置举行查找.粗看上去这两种思绪仿佛没什么大的差别,但是在实践中,这两种差别的实现思绪招致了宏大的差别.下面我们具体地加以观察.
在Smalltalk、Python、Ruby等动态面向对象语言中,实际办法的查找是按照办法名称举行的,其查找表构造以下:
由于这种查找表按照办法的名称举行办法查找,因此在查找历程中触及字符串对比,效率较差.但是这种查找表有一个突出的长处,就是有效空间操纵率高.为了阐明这一点,我们假定一个基类Base中有100个办法可供派生类改写(因此全部Base对象所同享的办法查找表有100项),而它的一个派生类Derived仅仅只打算改写此中5个办法,那么Derived类对象的办法查找表只需求5项.当一个办法调用发生的时刻,runtime按照被调用的办法名称在这个长度为5 的办法查找表中举行字符串查找,假如发现该办法在查找表中,则履行调用,不然将调用转寄(forward)给Base类履行.这是虚办法调用的尺度行为.当派生类实际改写的办法数目很少的时刻,可以将查找表安置成线性表,查找时次序对比,这种情形下有效空间操纵率到达100%.假如派生类实际改写的办法数目较多,那么可以采取散列表,假如采取公道的散列函数,一样可以在空间操纵率很高(普通可接近75%).. 的情形下实现办法的快速查找.该当注意到,由于编译器可以很简单地得到全部被改写办法的名称,因此可以履行尺度的gperf算法得到最优的散列函数.
以上是“<b>C++多态技术的实现和沉思</b>[VC/C++编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |