我想更多地了解" 为什么不能在switch语句中声明变量? "
我读了这篇文章,但我并没有完全理解.您可以在switch内部声明变量,但是要decalre并初始化变量或声明类的对象,它会给出complie time error.
请解释一下......
基本上是因为如果没有命中包含变量初始化的标签,则会跳过变量的初始化.这将是不好的,因为当且仅当初始化代码已经运行时,编译器才必须发出将破坏所述变量的代码.
例如:
class A { // has some non-trivial constructor and destructor }; switch (x) { case 1: A a; break; default: // do something else }
如果代码已经命中default
,则a
不会被初始化.编译器必须能够提前解决这个问题.可能出于性能原因,这是不允许的.
简单的解决方法是引入一个新的范围层:
class A { // has some non-trivial constructor and destructor }; switch (x) { case 1: { A a; } break; default: // do something else }
这样就可以了,a
现在很好地定义了破坏.
语言语法和常识之间存在冲突.对于我们这些人来说,看起来这段代码(取自1800 INFORMATION的答案)应该可以正常工作:
class A { // has some non-trivial constructor and destructor }; switch (x) { case 1: A a; break; default: // do something else }
毕竟,花括号定义了a的范围; 它只在我们输入案例1时创建,在离开案例1块后立即被销毁,除非我们进入案例1,否则它将永远不会被使用.事实上,情况标签和休息指令不分开范围,所以一个在所有的块存在之后,即使它在逻辑上是不可达.当然,从语法的角度来看,没有案例1块.
如果您将switch语句看作伪装的一堆(结构化)goto指令,则范围问题变得更加明显:
{ if (x == 1) goto 1; else goto default; 1: A a; goto end; default: // do something else end: }