通常在学校,我们的讲师会告诉我们总是在 switch case 语句的末尾包含一个 Default
语句。但是,我一直想知道所有(或大多数)场景是否有必要?
考虑以下 C++ 示例:
int num = rand()%3;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
上面的例子,我觉得不可能有可以>2或者<0的情况,那还需要加上Default
语句吗?
SO 中也有类似的问题,要求在 switch-case 中需要 Default
。那里给出的答复指出,我们几乎应该随时包含一个 Default
。但在我个人遇到的所有情况中,它似乎是多余的,因为永远无法达到 Default
。
编辑:另外,在防御性编程方面,这种情况是否需要Default
语句?
如果我要添加 Default
语句。它只会是一个错误处理
语句,我这样说对吗?
最佳答案
从技术上讲,不,你不需要,因为你已经用你的 switch 语句涵盖了所有可能的情况。
但是,无论如何,我总是发现在默认值中包含一个断言/异常是有用的。考虑以下场景:
// V1.0.0: Initial version.
int num = rand()%3;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
稍后...
// V1.0.0: Initial version.
// V1.0.1: Added a fourth method.
int num = rand()%4;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
}
在这种情况下,开发人员 #2 更新了 rand
模数,但实际上并没有添加 case 来处理 num == 4
。如果没有 default
,您将无声地失败,这可能会导致各种难以调试的错误。一个更易于维护的解决方案可能是:
// V1.0.0: Initial version.
// V1.0.1: Added a fourth method.
int num = rand()%4;
switch (num)
{
case 0: methodOne();
break;
case 1: methodTwo();
break;
case 2: methodThree();
break;
default:
assert(false);
throw InvalidNumException("BUG: Method has not been specified for value of num");
}
调试时,这会在断言处停止调试器,如果(上帝保佑)丢失的 case
一直到生产环境,您将抛出异常,而不仅仅是抛出异常逃跑并做不应该发生的事情。
编辑:
我认为包含一个 catch-all 是对防御性编程风格的一个很好的补充。如果您错过了 case
语句,它保证您将获得有用的结果(即使该有用的结果会导致程序崩溃)。
编辑 2:
正如 Andre Kostur 在对此答案的评论中提到的,如果您打开枚举并忘记处理 case
,一些编译器会发出警告,这是不包含 的一个很好的理由>default
枚举 switch 语句的大小写。引用Phresnel's answer了解更多相关信息。
关于c++ - 在这种情况下我需要 "Default"语句吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22910223/