2014-09-30 74 views
1

如何在switch语句中执行所有case而不重复现有的大型“all-in-one”情况?执行switch语句中的所有case - 特定问题

例如,

switch(obj.nObjType) 
{ 
case eElephant: 
... 
break; 
case eFoo: 
... 
break; 
case eSeptember: 
... 
break; 
default: 
return; 
} 

欲力执行代码对所有3个例(eElephant, eFoo, eSeptember)像没有break;,例如在nObjType = eAllTypes情况。

+0

您可以将该代码提取到函数中: void processElephant(); void processFoo(); void processSeptember()' 'case eElephant:processElephant();打破; case eFoo:processFoo();打破;默认:processElephant(); processFoo(); break;' – teivaz 2014-09-30 08:15:09

+0

@NirMH几乎总是有另一种方式。而最好的问题很大程度上取决于环境(关于我们在这里什么都不知道)。 – TobiMcNamobi 2014-09-30 08:21:30

+0

所以删除'break.'问题是什么?有什么意义?如果你想执行所有的代码,为什么要有'switch'声明呢? – EJP 2014-09-30 10:47:49

回答

3

然后使用if声明:

if (obj.nObjType == eElephant || obj.nObjType == eAllTypes) 
{ 
    // Elephant code 
} 

if (obj.nObjType == eFoo || obj.nObjType == eAllTypes) 
{ 
    // Foo code 
} 

// etc. 
+0

当obj.nObjType的值为'n'时,该解决方案不处理这种情况, t在枚举器列表上,就像'switch'语句中的'default'关键字一样。 – Akira 2017-05-02 11:52:23

5

你不能忽略休息。而是重构你的代码。

switch(obj.nObjType) { 
    case eElephant: 
    pokeElephant(); 
    break; 
    case eFoo: 
    barTheFoo(); 
    break; 
    case eSeptember: 
    rememberSeptember(); 
    break; 
    case eAllTypes: 
    pokeElephant(); 
    barTheFoo(); 
    rememberSeptember(); 
    break; 
    default: 
    return; 
} 
+1

我想你可以忽略它,如果你把它设置成一个'if(!all)break'将是完全丑陋的! – Surt 2014-09-30 08:18:04

+0

啊,我迟到了一秒钟,发布了一些非常相似的东西:-)。我想补充一点,避免重复代码总是好的,关键在于提取方法(如Amadan在此处所示)。 – TobiMcNamobi 2014-09-30 08:18:27

+0

@苏尔:哦。确实是的。正如你所说,你可以编写可以忽略中断的代码;但那真是太可怕了。 (并不是说我没有写过可怕的代码,但为什么给人一些想法?即使没有任何帮助,我们都会编写可怕的代码:P) – Amadan 2014-09-30 08:20:22

1

如果你把你的switch语句的功能,使您的obj有标志的列表而不是一个标志,你可以调用函数用列表中每个标志的switch语句。伪:

void dostuff(flag) 
    switch(flag) { 
     // ... 
    } 
} 

for (auto flag in obj.flags) { 
    dostuff(flag) 
} 
2

This answer是应该如何完成的。 不过:

我可以看到,这是很难找到,因为正确的解决方案,而不会产生大量的代码行 。谢谢@TobiMcNamobi,但在我的开关中有大约200个案例,因此为每个案例创建一个函数并不是一个好主意。 我认为,最好的可能是(不幸地)重复在 大案件中的所有案件。因为,我想,如果其他效率远低于 switch语句?

有了这么多的例子(你到底在干什么?)即使是提取方法,也会在switch语句的主体中留下200个额外的函数调用。这可能会很难快速维护。

这种情况下,我会做到以下几点:

switch(enum_variable) 
{ 
    case e_all: 

    case e_1: 
    e_1_function(); 
    if(enum_variable != e_all){break;} //** 

    case e_2: 
    e_2_function(); 
    if(enum_variable != e_all){break;} //** 

    //... 

    default: 
    break; 
} 

的线条标出//**将打破不拼尽全力的情况时。它实施起来很快(可以通过搜索和替换break;来完成),并做你想做的事情。
即使这样说,它仍然是一个非常糟糕的做法,但有时候必须做出例外。

不过我建议你不要把它作为未来使用的风格。您可能会发现,通过重新思考项目的工作流程可以做得更好,因为这可能会让您简化和改进。当然,我们不知道你在做什么,所以我不能提供更多的建议。

+0

同意。我想添加以下内容:1.“生成大量的代码行”不一定是坏的,只要这些行反映代码应该做的复杂性。 2.没有进一步的知识,我仍然发现为每个案例生成一个好主意的功能(相信我,ChestNoot:我正在用类似的代码自己摔跤)。至少它比重复更好。另一方面(正如Baldrickk指出的那样清楚而真实),由于项目/时间限制,它可能不适用。作为一个中级(!)解决方案Baldrickks的回答非常好。我强烈建议做单元测试。 – TobiMcNamobi 2014-09-30 10:38:40

+0

是的,将它分解成函数,在switch语句中没有代码(混合不同的抽象级别)。我试图避免的情况是,你错过了'e_all'情况下的函数之一,这很容易用200个奇怪的函数来复制。绝对不是一个_good_解决方案,就像你说的那样只是中间的,因此与Amadam的答案有关。 – Baldrickk 2014-09-30 10:47:56