私は、onClick std :: function型フィールドを持つButtonクラスを持っていて、 "setClickListener"メソッドはこのstd :: functionフィールドにラムダ関数を次のように設定します:C++ 11 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;
}
};
、私はラムダ関数を作成すると、ボタンのonClickの機能に設定しています:
#include "Button.h"
void onAnEventOccured() {
button->setClickListener([this]()->void {
// Do something
memberFunction();
anotherMemberFunction();
// etc...
});
}
void memberFunction() {
// Do some work...
}
void anotherMemberFunction() {
// Do some work...
}
さて、クリティカルセクションはonAnEventOccured方法は、アプリケーションの寿命の間に何度も呼ばれていることですラムダ関数が再び設定され、agaに。私はVisual Studio 2015を実行して、デバッグトレースポイントをstd :: functionクラスのdeconstructorに入れて、setClickListenerを設定している間にトレースポイントに達するのを見ることができます。これは、ボタンのインスタンスに格納されているこのラムダのonAnEventOccured関数とコピーバージョンの範囲を期待どおりに残しながら、破棄されたラムダ関数のデコンストラクタです。
これは正しいですか?このアーキテクチャ上にメモリリークはありますか?あなたは
あなたの2つの質問は完全に直交しているようです。そして、デストラクター上のトレースポイントまでは、匿名オブジェクトaka lambdaのデストラクタではなく、ラムダ別名の匿名オブジェクトをstd :: functionオブジェクトに変換するときに作成される一時的な 'std :: function'オブジェクトです。 – Arunmu
メモリリークはなく、一時的なものは破棄されます。私はあなたの他の質問に答えることができません。なぜなら、メンバー関数の外で 'this'を使用しようとするので、コードの2番目の断片が無効であるからです。 あなたがしようとしていることを理解していれば、破棄される可能性のあるオブジェクトに応じて 'std :: function'があります。おそらく、あなたの関数オブジェクトの型が 'std :: function 'ボタンを明示的に渡すことができます。 –
EdMaster
コメントありがとうございます。 @EdMaster、私はあなたの懸念を知っている、私はアプリケーションで私の現在の画面であり、積極的に描画するので、 "this"ポインタが有効であることを保証します。 –