请考虑以下代码:
void foo()
{
{
CSomeClass bar;
// Some code here...
goto label;
// and here...
}
label:
// and here...
}
是否会调用bar的析构函数?
答案 0 :(得分:57)
C ++标准说:
退出范围时(但是 完成),析构函数(12.4)是 要求所有构造的对象 具有自动存储持续时间 (3.7.2)(命名对象或临时对象) 在该范围内声明的,在 他们的相反顺序 声明。
所以答案是肯定的。
答案 1 :(得分:24)
是的,他们会被召唤。
更新的 (这样做是可以的,getos并不比抛出虚拟异常或者使用bools / ifs更糟糕。函数中的简单goto不会使它成为意大利面条代码。)
答案 2 :(得分:8)
1)是的。 2)不要这样做。
详细说明:从概念上讲,这与通过break
留下循环没有什么不同。但是,强烈建议goto
强烈劝阻。几乎没有必要使用goto
,应仔细检查任何用途,以了解发生了什么。
答案 3 :(得分:5)
是的,正如其他人所说的那样。 C ++指定/强制执行此操作。
但只是为了完整性而添加:如果您的goto
使用在某些编译器中找到的计算 - goto
扩展名 - gcc,clang,可能是其他人,但不是包括最后我知道的MSVC - 对象的析构函数是否会被调用是非常模糊的。当goto
转到单个位置时,在控制流转移之前必须调用哪些析构函数非常清楚。但是使用计算的goto
,可能需要动态调用不同的析构函数,以提供"期望的"语义。在这些情况下,我不确定实现此扩展的编译器是做什么的。我遇到这个问题的记忆就是当一个计算出来的goto
可能会让一个带有非trival析构函数的对象的范围时,clang会发出警告,声称析构函数不会被调用。在某些情况下可能没问题,有些情况则没有。我不知道其他编译器会做什么。如果你想使用带有非平凡析构函数的对象计算goto
s,请注意这个问题。