二重调度(一):什么是二重调度?

有时,借用一下Jacqueline Susann的话:一次是不够的。例如你有着一个光辉形象、
崇高声望、丰厚薪水的程序员工作,在Redmond,Wshington的一个著名软件公司--当然,我说的就是任天堂。为了得到经理的注意,你可能决定编写一个video game。游戏的背景是发生在太空,有宇宙飞船、太空站和小行星。 
在你构造的世界中的宇宙飞船、太空站和小行星,它们可能会互相碰撞。假设其规则

是:

 

1、如果飞船和空间站以低速接触,飞船将泊入空间站。否则,它们将有正比于相对

速度的损坏。 


2、如果飞船与飞船,或空间站与空间站相互碰撞,参与者均有正比于相对速度的损

坏。 


3、如果小行星与飞船或空间站碰撞,小行星毁灭。如果是小行星体积较大,飞船或

空间站也毁坏。 


4、如果两个小行星碰撞,将碎裂为更小的小行星,并向各个方向溅射。

 

这好象是个无聊的游戏,但用作我们的例子已经足够了,考虑一下怎么组织C++代码以
处理物体间的碰撞。 
我们从分析飞船、太空站和小行星的共同特性开始。至少,它们都在运动,所以有一

个速度来描述这个运动。基于这一点,自然而然地设计一个基类,而它们可以从此继承。实际上,这样的类几乎总是抽象基类,


class GameObject { ... }; 
class SpaceShip: public GameObject { ... }; 
class SpaceStation: public GameObject { ... }; 

class Asteroid: public GameObject { ... }; 


现在,假设你开始进入程序内部,写代码来检测和处理物体间的碰撞。你会提出这样
一个函数: 
void checkForCollision(GameObject& object1, 
                       GameObject& object2) 

  if (theyJustCollided(object1, object2)) { 
    processCollision(object1, object2); 
  } 
  else { 
    ... 
  } 


问题来了。当你调用processCollision()时,你知道object1和object2正好相撞,
并且你知道发生的结果将取决于object1和object2的真实类型, 但你并不知道其真实类型;你所知道的就只有它们是GameObject对象。如果碰撞的处理过程只取决于object1的动态类型,你可以将processCollision()设为虚函数,并调用

object1.processColliion(object2)。 如果只取决于object2的动态类型, 也可以同样处理。但现在,取决于两个对象的动态类型。虚函数体系只能作用在一个对象身上,它不足以解决问题。 你需要的是一种作用在多个对象上的虚函数。C++没有提供这样的函数。可是,你必须要实现上面的要求。现在怎么办呢? 


一种办法是扔掉C++,换种其它语言。比如,你可以改用CLOS(Common Lisp Object 

System) 。CLOS支持绝大部分面向对象的函数调用体系中只能想象的东西:multi-method。multi-method是在任意多的参数上虚拟的函数,并且CLOS更进一步的提供了明确控制“被重载的multi-method将如何调用”的特性。 


让我们假设,你必须用C++实现,所以必须找到一个方法来解决这个被称为“二重调度
(double dispatch) ” 的问题。
(这个名字来自于object-oriented programming community,在那里虚函数调用的术语是“message dispatch” ,而基两个参数的虚调用是通过“double dispatch”实现的,推而广之,在多个参数上的虚函数叫“multiple dispatch” 。 )有几个方法可以考虑。但没有哪个是没有缺点的,这不该奇怪。C++没有直接提供“double dispatch” ,所以你必须自己完成编译器在实现虚函数时所做的工作(见Item M24) 。如果容易的话,我们可能就什么都自己做了,并用C语言编程了。我们没有,而且我们也不能够,
所以系紧你的安全带,有一个坎途了。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值