Quando catturo un oggetto per riferimento in un lambda C++ 11, lascia l'oggetto fuori dall'ambito e quindi esegue il lambda, ha ancora accesso all'oggetto. Quando eseguo il seguente codice, la chiamata lambda può ancora accedere all'oggetto, sebbene il distruttore sia già stato chiamato! Qualcuno può spiegare perché questo funziona e perché non ottengo un errore di runtime?Lambda Capture and Memory Management
#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;
}
ecco l'output:
MyClass created!
MyClass destroyed!
5
has enough health
Sospetto che si tratti di comportamento non definito, e in questo caso il comportamento non definito è "l'oggetto sembra essere vivo e vegeto". – templatetypedef
Comportamento non definito. Vedere http://c-faq.com/ansi/experiment.html –
Se si esegue questo attraverso un analizzatore di perdite di memoria (come Valgrind), sarà (si spera) che si sta accedendo a un oggetto morto. –