新客网WWW.XKER.COM:致力做中国最专业的网络学院!
学院: 操作系统 - 网络应用 - 服务器 - 网络安全 - 工具软件 - 办公软件 - Web开发 - 数据库 - 网页设计 - 图形图像 - 媒体动画 - 硬件学堂 - 存储频道 - QQ专区
您的位置:首页 > 软件开发 > 开发语言 > C++ > 正文:C++多态技术的实现和反思

C++多态技术的实现和反思

新客网 XKER.COM 2006-04-28 来源: 收藏本文


  另一种虚方法查找方案则是C++ 开发者十分熟悉的,基于绝对位置的定位技术。其查找表结构非常简单,仅仅是一个存放了方法地址的指针数组。表中的每一项不具有自描述性,只有编译器在编译时知道它们究竟分别对应着哪一个方法,并且将对于方法的调用代码编译成一个紧凑的指针+偏移的调用的硬编码。这种查找表的最大特点就是高效率,基于这种查找表进行方法调用仅仅需要多做一次数组内的随机访问操作。在所有我们所能想到的“增加一个间接层”的方案中,这种方案在效率上是最高的。但是使用这种方案有一个限定,就是要求所有同族多态对象具有完全一样的查找表。也就是说,你必须确保所有实现了某个接口的对象的虚方法查找表的第k 项都具有相同的语义。假设一个基类有100个可供改写的虚方法,那么它的虚方法查找表共有100项(实际上就是100个指向方法入口地址的指针)。而其所有派生类对象都必须有结构上完全相同的、长度至少为100项的虚方法查找表。现在假设我们开发的一个派生类中只改写了基类的5个方法,那么这个派生类对象所共享的虚方法表仍然长达100项,只不过其中95项与其基类对象虚方法查找表中相应的项一模一样,只有5项具有实际意义——正是这5项的存在才使派生类的存在有了意义。

  在这种情况下,该方法表的实际有效利用率只有可怜的5%。总的来说,这一方案执行效率最优,但是并不适用于所有的场合。

  当然,看上去上述两种虚方法调用实现技术效果完全一样,一切都被掩盖在编译器之下,与一般开发者毫无关系。但是,事实真的如此吗?我们在下面会看到,C++ 的这种查找表结构构成了C++应用开发中最险恶的技术陷阱之一。

  两种不同的多态性应用场景

  学习过数值分析的读者应该熟知,在矩阵运算的电算求解领域,低阶稠密矩阵的求解与高阶稀疏矩阵的求解是性质完全不同的两个问题,其存储方案和求解算法截然不同。非常有趣的是,在多态性的实际应用中,也有着与矩阵问题类似的两种性质上截然不同的场景。

  第一种场景中,我们所构造的对象比较简单,同一族系中兄弟类总数不多,而彼此之间的差异较大,因此对象中的虚方法数量少,而改写率高。我们通常在教科书上所接触的面向对象例子,以及在一般应用领域中接触的对象都属此类。

  例如一个Modem类,即使其具有较多的特性,虚方法总数也很难超过20个,而不同的Modem类实现,可能会改写其中大部分甚至全部虚方法。另一个例子是COM接口。由于COM组件思想基于接口,而一个粒度良好的接口必然是“瘦小精干”的。比如IMalloc接口只有6个方法(不包括从IUnknown继承来的3 个方法),IPersistFile共5个方法,通常用户自己写的COM接口中的方法数量也不超过20。而在实现COM接口是,几乎总是需要改写全部方法。这与低阶稠密矩阵非常相似,因此值得用最简单直接的查找表结构来实现——速度快,而且简单直接。由于虚方法改写率高,查找表中的有效利用率较高。这种场景是C++多态性实现技术大大的用武之地,可以说C++特色的虚方法调用机制就是用来应对这种应用的。

  而第二种应用场景截然不同,在这种场景中,对象比较复杂,特性稠密,行为变化多端,同一族系中兄弟对象数量庞大,而彼此之间大同小异。此种对象中的虚方法数量多,而改写率低。GUI系统视频游戏是这种应用场景的典型代表。由于我们整天与Windows 系统打交道,所以用Windows GUI系统来说明这种场景是最合适不过的了。我们知道,在Windows图形界面上的几乎所有实体从概念上讲都是Window对象,因此构成了一个对象族系。这个族系有三个突出的特点。一是行为多,特征多变(或者说虚方法数量多)。Microsoft Windows系统直接定义了数百个窗口消息,并允许用户使用WM_USER+n和WM_APP+n的方式定义新的消息,用面向对象的话来说,就相当于给Windows系统中的所有Window对象定义了数百个可供改写的虚方法,并且还允许用户自由扩展新的虚方法。

共4页: 上一页 [1] [2] [3] [4] 下一页
收藏】 【评论】 【推荐】 【投稿】 【打印】 【关闭
发表评论
要记得去论坛讨论,点击注册新会员匿名评论
评论内容:不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
阅读排行
随机推荐
实用信息推荐