【发布时间】:2013-02-08 00:03:49
【问题描述】:
当我在 C++11 lambda 中通过引用捕获对象时,让对象超出范围,然后执行 lambda,它仍然可以访问该对象。当我执行以下代码时,lambda 调用仍然可以访问该对象,尽管已经调用了析构函数!有人可以解释为什么这有效以及为什么我没有收到运行时错误吗?
#include <iostream>
class MyClass {
public:
int health = 5;
MyClass() {std::cout << "MyClass created!\n";}
~MyClass() {std::cout << "MyClass destroyed!\n";}
};
int main(int argc, const char * argv[])
{
std::function<bool (int)> checkHealth;
if(true) {
MyClass myVanishingObject;
checkHealth = [&myVanishingObject] (int minimumHealth) -> bool {
std::cout << myVanishingObject.health << std::endl;
return myVanishingObject.health >= minimumHealth;
};
} // myVanishingObject goes out of scope
// let's do something with the callback to test if myVanishingObject still exists.
if(checkHealth(4)) {
std::cout << "has enough health\n";
} else {
std::cout << "doesn't have enough health\n";
}
return 0;
}
这是输出:
MyClass created!
MyClass destroyed!
5
has enough health
【问题讨论】:
-
我怀疑这是未定义的行为,在这种情况下,未定义的行为恰好是“对象似乎还活着”。
-
未定义的行为。见c-faq.com/ansi/experiment.html
-
如果您通过内存泄漏分析器(例如 Valgrind)运行它,它会(希望)报告您正在访问一个死对象。
标签: c++ memory-management c++11 lambda