在这种情况下,我需要"默认"声明吗?

use*_*460 4 c++ default case switch-statement

通常在学校,我们的讲师会告诉我们Default在转换案例陈述的最后总是包含一个陈述.但是,我一直想知道所有(或大多数)场景是否必要?

考虑C++中的以下示例:

int num = rand()%3;
switch (num)
{
   case 0: methodOne();
           break;
   case 1: methodTwo();
           break;
   case 2: methodThree();
           break;
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我觉得不可能有一个> 2或<0的情况,所以我还需要包含一个Default声明吗?

在SO中有类似的问题,需要Default在switch-case中.那里的回复表明我们几乎可以在任何时候包括一个Default.但在我个人遇到的所有情况中,它似乎是多余的,因为Default永远无法达到.

编辑:此外,在防御性编程方面,这种情况需要一个Default声明吗?如果我要添加一个Default声明.这只是一个error-handling声明,我说得对吗?

Kar*_*oll 6

从技术上讲,不,你没有,因为你已经用switch语句覆盖了所有可能的情况.

但是,我始终认为在默认情况下包含断言/异常很有用.请考虑以下情形:

// V1.0.0: Initial version.
int num = rand()%3;
switch (num)
{
   case 0: methodOne();
           break;
   case 1: methodTwo();
           break;
   case 2: methodThree();
           break;
}
Run Code Online (Sandbox Code Playgroud)

后来...

// 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;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,开发人员#2更新了rand模数,但实际上没有添加要处理的案例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");
}
Run Code Online (Sandbox Code Playgroud)

在调试时,这会在断言处停止调试器,如果(上帝禁止)丢失case使它一直到生产,你将得到一个异常抛出,而不是只是跑掉并做一些不应该发生的事情.

编辑:

我认为包括一个全能的防守编程风格是一个很好的补充.如果您错过了一个case声明(即使有用的结果是导致程序崩溃),它可以保证您获得有用的结果.

编辑2:

正如Andre Kostur在对此答案的评论中提到的,如果你打开枚举并忘记处理a,一些编译器会发出警告case,这是不包括default枚举开关语句的一个很好的理由.有关详细信息,请参阅Phresnel的答案.