【发布时间】:2021-01-03 06:04:03
【问题描述】:
假设有一个对象具有自动存储持续时间,并且该对象是从嵌套范围内复制初始化的,例如循环体。从嵌套范围内创建的值的生命周期是否扩展到包含范围?
#include<iostream>
using namespace std;
class Thing {
public:
int data;
Thing(int data) : data(data) { cout << "making a thing" << endl; }
~Thing() { cout << "destroying a thing" << endl; }
};
int main() {
Thing t = Thing(-1);
for (int i = 0; i < 4; i++) {
t = Thing(i); // this is both created AND destroyed from within this scope...?
}
cout << t.data << endl; // undefined behavior?
}
现在,最后访问t.data 是可行的,但我看到每个Thing 的析构函数在每次循环迭代时都会调用一次,所以我可能只是走运了?
这看起来很相关(但我不是律师,所以很难破译):some 2011 c++ standard
具体来说:
- 对于这种不具有可变长度数组类型的 [具有自动存储持续时间] 的对象,其生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束......李>
因此,如果我的代码 sn-p 是未定义的行为 - 对于循环体更改局部变量,该局部变量应该手动堆分配,然后手动释放,或者...?
【问题讨论】:
-
t总是指的是同一个Thing。表达式t = Thing(i);不会改变t对象所引用的whichThing。它只是创建一个临时的新Thing,将该值复制到名为t的Thing,然后销毁临时Thing。这是价值语义,可能会让具有 C# 和 Java 等其他语言背景的开发人员感到惊讶。 -
不要阅读典型问题的标准,这确实非常困难(显然)。 cppreference 是参考的最佳默认选择。
标签: c++