我正在阅读 C++ 第 6 章初始化和清理中的思考。作者说:
实际上,编译器更有可能遵循 C 中的做法,即在该范围的左大括号处为该范围分配所有存储空间。没关系,因为作为程序员,在定义之前您不能访问存储。尽管存储是在块的开头分配的,但构造函数调用直到定义对象的序列点才会发生,因为在此之前标识符不可用。编译器甚至会检查以确保您没有将对象定义放在序列点仅有条件地通过它的位置,例如在 switch 语句中或 goto 可以跳过它的地方。
然后作者举了一个例子如下:
class X {
public:
X();
};
X::X() {}
void f(int i) {
if(i < 10) {
//! goto jump1; // Error: goto bypasses init
}
X x1; // Constructor called here
jump1:
switch(i) {
case 1 :
X x2; // Constructor called here
break;
// case 2 : // Error: case bypasses init
X x3; // Constructor called here
break;
}
}
int main() {
f(9);
f(11);
}///:~
我不明白为什么上面的代码可以?据我了解,如果不是x2
可以绕过初始化。i
1
补充:
这句话“实际上,编译器更有可能遵循 C 中的做法,在该范围的左大括号处为一个范围分配所有存储空间。” 也让我很困惑。
根据作者的描述,在 的左大括号处switch
,编译器已经为x2
and分配了空间x3
。如果是这种情况,则有x2
可能未初始化(不满足情况 1)。