我簡化了代碼,使其仍然存在問題。此代碼應該打印「42」,而是打印一個不同的數字。我還在析構函數中打印了「祕密」對象的地址,並在訪問它時顯示它已被破壞得太早。我在這裏做錯了什麼,或者這可能是編譯器的問題?C++析構函數太早調用
代碼:
#include <iostream>
using namespace std;
struct Secret{
int value;
Secret(int value):value(value){}
~Secret(){
cout<<"destructor:"<<(void*)this<<endl;
value=0;
}
};
template<class Func>
class Copier{
public:
Func func;
Copier(Func func):func(func){}
void run(){
func();
}
auto copy(){
auto output = [this](){
func();
};
Copier<decltype(output)> out(output);
return out;
}
};
auto makeSecretPrinter(){
Secret secret(42);
auto secretPrinter = [secret](){
cout<<"reading object at address:"<<(void*)&secret<<endl;
cout<<"the secret is:"<<secret.value<<endl;
};
return Copier<decltype(secretPrinter)>(secretPrinter).copy();
}
int main(){
makeSecretPrinter().run();
return 0;
}
鐺(版本3.5-1ubuntu1)輸出:
destructor:0x7fff9e3f9940
destructor:0x7fff9e3f9938
destructor:0x7fff9e3f9948
destructor:0x7fff9e3f9950
reading object at address:0x7fff9e3f9940
the secret is:0
GCC(Ubuntu的4.9.2-0ubuntu1〜14.04)4.9.2輸出:
destructor:0x7fff374facc0
destructor:0x7fff374facb0
destructor:0x7fff374faca0
destructor:0x7fff374fac90
reading object at address:0x7fff374facc0
the secret is:-1711045632
捕獲'this'意味着用指針語義捕獲。如果捕獲的對象被銷燬,那麼你可能不會取消引用該指針(甚至不會隱式地執行,就像'copy'的'output' lambda中所做的那樣)。複製該lambda複製捕獲的指針,即執行淺拷貝。 – dyp 2014-12-08 02:21:31
'auto output = [this](){'這條線似乎是問題所在。你真的想複製'* this'而不是一個指針 – 2014-12-08 02:22:30
@BryanChen正是我想的:http://coliru.stacked-crooked.com/a/43b70f00c4a20469 – dyp 2014-12-08 02:23:36