处理很多if-else,切换

时间:2010-09-01 11:57:42

标签: c++ if-statement switch-statement

处理这样的事情的最佳方法是什么:

if(key==Space)
{
    switch(weapon)
    {
        case GUN:
            p->shotGun();
            break; 
        case BOW:
            p->shotBow();
            break;
    }
}
else if(key==Enter)
{
    //...
}
else if(key==Up)
{
    //...
}

9 个答案:

答案 0 :(得分:10)

将一个维度拆分为两个:

switch (key)
{
  case Space:
    ProcessSpaceCmd ();
    break;

  case Enter:
    ProcessEnterCmd ();
    break;

  case Up:
    ProcessUpCmd ();
    break;
}

查看更长的维度[key][weapon],并选择最短的外部切换。

答案 1 :(得分:9)

您可能需要考虑使用Command和/或Strategy模式。 Command模式似乎非常适合外部if / else,而策略模式似乎非常适合内部切换。

  cmd = Command->GetCommand( key );
  cmd->Perform();

并执行与空格键关联的命令

  weapon = PlayState->GetCurrentWeapon();
  weapon->Fire();

注意后者依赖于一些全局缓存/状态来保存当前武器(策略)。

这样做的效果是将if / else逻辑移动到您确定当前命令的工厂方法中。选择哪个命令选择其中一个if / else分支。将当前武器存储在游戏状态允许您轻松选择要调用的武器的Fire方法,因此选择武器的开关“逻辑”将移动到状态的武器选择逻辑并完全“消失”。每种武器策略都只知道如何执行它自己的“火”逻辑。

答案 2 :(得分:5)

我倾向于使用地图类型表达式:

unordered_map<KEY_PRESS,ICommand> myCommands;
unordered_map<KEY_PRESS,ICommand>::const_iterator currentCommand = myCommands.find( key );
if( currendCommand != myCommands.end() ){
    currentCommand->performAction( weapon );
}

然后,再次,如果你把武器变成对象而不是标志,你就可以使用重载的函数模式。

答案 3 :(得分:3)

由于它是C ++,您可能希望利用它的面向对象方面。为IProjectileWeapon等武器创建一个界面,并创建一个实现该界面的弓箭类。然后,当您调用Shoot()方法时,它将使用正确的行为。这将摆脱武器的开关声明。将Character类作为成员并使用UseWeapon()作为方法可能会更好。所以UseWeapon()方法会调用武器的Shoot()方法。

要移动,请将移动命令添加到Character类,并传递角色应移动的方向。

答案 4 :(得分:2)

或者如果你真的想摆脱if-elses,你可以在键码和方法之间使用某种形式的映射。根据密钥代码是否连续,它可以是映射,或者只是由密钥代码索引的数组,如:

KeyMethods[key]();

答案 5 :(得分:2)

另一种可能性:

class Weapon {
    public:
    abstract void shoot();
}

class Gun: public Weapon {
    public:
    void shoot();
}

class Bow: public Weapon {
    public:
    void shoot();
}

if(key==Space)
{
    weapon.shoot();
}
else if(key==Enter)
{
    //...
}
else if(key==Up)
{
    //...
}

至于if一长串的陈述,那很好。一个switch语句也适用于IFF,你正在使用整数。但是每个人都有break陈述可能会分散注意力,忘记它可能是灾难性的。如果在内循环中需要速度以获得性能关键代码,这一点更为重要。 (else if依次评估每一个,直到找到匹配为止。switch直接跳转到正确的选项。)

答案 6 :(得分:1)

嵌套switch语句的级别如何?为了更好的可读性,我还将重构二级开关以分离功能。

答案 7 :(得分:0)

我建议至少将每个If的内容分成它自己的函数。

if(key == Space)
    FureCurrentWeapon();
else if(key == Enter)
    Activate();
else if(key == Up)
    WalkForwards();

我之前使用的另一种方法是创建一个基类,该基类可以从接收键盘输入的每个类派生。保留一个从它派生的类列表,然后在每次接收输入时迭代该列表,传递按下的键并让它们处理它们。如果需要的话。

答案 8 :(得分:0)

让你的武器类成为虚拟。