我想更多地了解" 为什么不能在switch语句中声明变量? "
我读了这篇文章,但我并没有完全理解.您可以在switch内部声明变量,但是要decalre并初始化变量或声明类的对象,它会给出complie time error.
请解释一下......
180*_*ION 20
基本上是因为如果没有命中包含变量初始化的标签,则会跳过变量的初始化.这将是不好的,因为当且仅当初始化代码已经运行时,编译器才必须发出将破坏所述变量的代码.
例如:
class A
{
// has some non-trivial constructor and destructor
};
switch (x)
{
case 1:
A a;
break;
default:
// do something else
}
Run Code Online (Sandbox Code Playgroud)
如果代码已经命中default,则a不会被初始化.编译器必须能够提前解决这个问题.可能出于性能原因,这是不允许的.
简单的解决方法是引入一个新的范围层:
class A
{
// has some non-trivial constructor and destructor
};
switch (x)
{
case 1:
{
A a;
}
break;
default:
// do something else
}
Run Code Online (Sandbox Code Playgroud)
这样就可以了,a现在很好地定义了破坏.
语言语法和常识之间存在冲突.对于我们这些人来说,看起来这段代码(取自1800 INFORMATION的答案)应该可以正常工作:
class A
{
// has some non-trivial constructor and destructor
};
switch (x)
{
case 1:
A a;
break;
default:
// do something else
}
Run Code Online (Sandbox Code Playgroud)
毕竟,花括号定义了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:
}
Run Code Online (Sandbox Code Playgroud)