C++ C++;设计问题

C++ C++;设计问题,c++,oop,C++,Oop,我有这样的类层次结构: Entity Stationary Tree Creature Bear Crow 我有一个世界和一个球员。当玩家碰到什么东西时,它会得到一个调用handleCollision(Entity*Entity),然后根据不同的情况发生不同的事情;如果玩家撞到一棵树上,当玩家攻击一只熊时,什么也不会发生。问题是我不知道如何以一种好的方式区分不同的案例 我想到的一个想法是这样的。Player

我有这样的类层次结构:

Entity  
    Stationary  
        Tree  
    Creature  
        Bear  
        Crow  
我有一个世界和一个球员。当玩家碰到什么东西时,它会得到一个调用handleCollision(Entity*Entity),然后根据不同的情况发生不同的事情;如果玩家撞到一棵树上,当玩家攻击一只熊时,什么也不会发生。问题是我不知道如何以一种好的方式区分不同的案例


我想到的一个想法是这样的。Player::handleCollision(Entity*)调用Entity->handleCollisionHelper(Player&)。这是一个虚拟函数,它在树中不做任何事情,在生物中(它应该攻击所有生物)调用Player.handleCollisionCreature(This),然后将攻击代码放入handleCollisionCreature。有没有更好的方法不用RTTI(typeid等)来实现这一点呢?

使用(Player&Player)arg的虚拟方法似乎是非常好的面向对象设计。正如您所说的,您可以添加某种形式的类型,或者通过排列使用RTTI和switch case,但这将是非常C风格的函数式。只要你不是每秒进行数千次虚拟呼叫,你就应该没事。

只是为了提供官方名称的参考-这个问题称为双重分派(你需要根据两个对象的类型同时决定做什么)


有关详细信息和建议的解决方案,请参阅Wikipedia文章。

与其触发Entity*,不如使用以下内容:

 handleCollision(Stationary& stationary)
 {
     // Nothing to do yet?
 }

并删除实体*函数。这将确保只有生物才会开始战斗(将StartCobat功能添加到你的生物类中)。或者,你可以有一个战斗类:

 handleCollision(Creature& creature)
 {
     Combat::Begin(this, creature);
 }

我想你要找的是“或”


根据多个对象的动态类型调用不同的函数不是C++的内置特性,但有许多众所周知的技术可以自己滚动。您提出的级联调用可能是最常见的一种

你现在做的很好。这叫做双重分派,在这种情况下是一种常见的模式。我不知道为什么每个人都认为这是双重分派。我们只有一个变量类型的对象(与(实体)碰撞的对象)。等式的另一边有一个固定类型的对象(玩家)。因此,这是单一分派,因此虚拟函数是实现解决方案的完美方式。Martin,仅使用单一分派来实现这一点的方式需要实体基类(和派生类)中的“CollideWithPlayer()”等方法。这是可能的,但相当有限-当您希望突然开始支持与其他对象的碰撞时会发生什么?或者当玩家也是一个基类并且可能有不同的子类与特定的碰撞?根据具体情况,这可能是一个可行的解决方案。可能不是在这里描述的上下文中。为什么他需要双重调度。我只看到一个可能有不同类型的对象(被击中的对象)。另一方面,击球的对象总是一名球员。因此,这是通过虚拟函数实现的单一分派。
 handleCollision(Creature& creature)
 {
     Combat::Begin(this, creature);
 }