ich einen Button-Klasse haben, die eine onClick std :: function typisierten Feld und "setClickListener" Methode haben setzt jede Lambda-Funktion auf diese std :: Funktionsfeld wie folgt:C++ 11 Lambda-Nutzung als Delegierter mit std :: function
#include <functional>
class Button {
public:
void doSomething() {
if(onClick) {
onClick();
}
}
typedef std::function<void()> OnClickListener;
OnClickListener onClick;
void setClickListener(OnClickListener onClickCallBack) {
onClick = onClickCallBack;
}
};
In meinem Anwendungscode, ich schaffe eine Lambda-Funktion und Einstellung onClick Funktion der Taste wie unten zu sehen:
#include "Button.h"
void onAnEventOccured() {
button->setClickListener([this]()->void {
// Do something
memberFunction();
anotherMemberFunction();
// etc...
});
}
void memberFunction() {
// Do some work...
}
void anotherMemberFunction() {
// Do some work...
}
Nun ist der kritische Abschnitt dass onAnEventOccured Methode viele Male während der Anwendung des Lebens genannt Zyklus und die Lambda-Funktion wird erneut und aga gesetzt im. Ich laufe auf Visual Studio 2015 und setzen Debug-Trace-Punkt auf den Dekonstruktor der Klasse std :: function und kann sehen, dass es tracepoint trifft, während setClickListener gesetzt wird. Ich denke, das ist der Dekonstruktor der Lambda-Funktion, der zerstört wurde, während der Geltungsbereich der onAnEventOccured-Funktion verlassen wurde und die Version dieses Lambdas wie erwartet in der Button-Instanz gespeichert wurde.
Bin ich richtig? Gibt es ein Speicherleck auf dieser Architektur?
Ihre beiden Fragen scheint völlig orthogonal. Und soweit der Trace-Punkt auf Destruktor geht, ist es wahrscheinlich das temporäre 'std :: function'-Objekt, das beim Konvertieren Ihres anonymen lambda-Objekts in das std :: function-Objekt, nicht des Destruktors des anonymen Objekts aka lambda, erzeugt wird. – Arunmu
Es gibt kein Speicherleck, die Provisorien sind zerstört. Ich kann Ihre anderen Fragen nicht beantworten, da Ihr zweites Code-Fragment ungültig ist, weil Sie versuchen, 'this' außerhalb einer Member-Funktion zu verwenden. Wenn ich verstehe, was Sie zu tun versuchen, hätten Sie eine 'std :: function' abhängig von einem Objekt, das möglicherweise zerstört wird, vielleicht können Sie Ihr Funktionsobjekt vom Typ 'std :: function 'damit Sie den Button auch explizit übergeben können. –
EdMaster
Danke für Kommentare. @EdMaster, ich kenne deine Bedenken und ich garantiere, dass "dieser" Zeiger gültig ist, weil es mein aktueller Bildschirm in der Anwendung und Rendering aktiv ist. –