c++ - 在这种情况下我需要 "Default"语句吗?

标签 c++ switch-statement case default

通常在学校,我们的讲师会告诉我们总是在 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/

相关文章:

c++ - C 套接字 : Echo server bad reply

c# - 有比 'switch on type' 更好的选择吗?

c - 在 switch 语句中声明和初始化的变量

java - Java 中区分大小写的问题

SQL 按年龄范围和性别对患者进行分组

sql - 带有 CASE 的 Postgres 自定义函数

c++ - 如何在 Visual Studio 解决方案构建期间限制并行 cl.exe 进程的数量?

c++ - 使用堆栈加密字符串

c++ - 无法创建 QFile(仅适用于 msvc2017 uwp)

c++ - 在切换循环周期结束时未显示的游戏总数