【发布时间】:2016-09-09 11:32:30
【问题描述】:
在这个小例子中,一个对象被多次破坏...
可以在以下位置找到输出:http://ideone.com/ddJ6Hh
#include <iostream>
#include <string>
#include <memory>
#include <functional>
using namespace std;
struct sA
{
static int n;
int id;
string name;
sA(string s="default"):id(++n),name(s) { cout<<"object '"<<name<<"' created\t id="<<id<<"\taddr="<<this<<"\tn="<<n<<"\n"; }
~sA() { cout<<"object '"<<name<<"' destroyed\t id="<<id<<"\taddr="<<this<<"\tn="<<--n<<"\n"; }
// sA(const sA& other):id(++n),name(other.name+"_Copy") { cout<<"object '"<<name<<"' copied\t id="<<id<<"\taddr="<<this<<"\tn="<<n<<"\n"; }
sA operator=(const sA& other) =delete;
};
int sA::n;
int main()
{
function<void(void)> vp;
{
sA f("1___This Object will die when others need it...");
sA b("2___This Object will not die ...");
vp=[&f,b]
{
cout<<"Hello\n";
cout<<b.name<<"||\t addr="<<&b<<"\t|<*>| Stack Data is ok\n";
cout<<f.name<<"||\t addr="<<&f<<"\t|<*>| Stack Data may not be there\n";
};
vp();
cout<<"********* Block end\n";
}
sA k("3__test obj");
vp();
return 0;
}
到目前为止,我想出的可能原因是:
1) lambda 获取的本地对象的引用超出了活动范围。[for object 'f']
2) 调用默认拷贝构造函数,旧拷贝被销毁 [for object b]
但这些原因并不能回答以下事实:
1) 即使在最里面的块结束之前,两个对象也被破坏了。 [区块结束识别]
2) 最多必须有 1 个额外的破坏,但它显示 3。[作为程序末尾的 n=-3]
3) 如果我以递归方式启用复制构造函数,则正在创建副本,但最后“构造的总数=破坏的总数”。 [在程序结束时 n=0]
这是 lambda(不可变)的行为吗?
或者它只是代码中的另一个错误?
还有什么是 lambda 及其捕获的变量的生命周期?
【问题讨论】:
-
此段错误(其他地方)因为您在 lambda
vp=[&f,b]中通过引用f捕获,然后尝试在外部块范围之后使用vp()再次调用它,因为引用不再有效.你调用了未定义的行为。 -
你的对象没有被销毁 2 次它的副本被销毁,因为在 clusore
b被值捕获 -
如果在移动和复制构造函数中增加
n(自动生成的构造函数不会这样做),n最终将变为 0。 -
提示:将
cout<<this添加到您的构造函数和析构函数中。 -
cout
标签: c++ function c++11 lambda scope