クラス メンバー関数をコールバックとして渡す
オブジェクト指向プログラミングでは、クラス メンバー関数をコールバックとして渡す必要がある場合があります。外部 API。ただし、これを直接試みると、次のシナリオに示すように、コンパイル エラーが発生する可能性があります。
m_cRedundencyManager->Init(this->RedundancyManagerCallBack);
コンパイラは、関数ポインタの引数リストが欠落していると警告し、代わりに &CLoggersInfra::RedundancyManagerCallBack の使用を提案します。ただし、これでもコンパイルに失敗します。
メンバー関数について
解決策を詳しく調べる前に、メンバー関数の本質を理解することが重要です。 C では、メンバー関数は基本的に、追加の隠しパラメータ this を持つ通常の関数です。この隠しパラメータは、関数が属するオブジェクト インスタンスを表します。
次の例を考えてみましょう:
class A { public: int data; void foo(int addToData) { data += addToData; } };
関数 A::foo は 1 つのパラメータを受け取りますが、内部的には 2 つのパラメータで動作します。 : addToData とこれ。後者は、foo が呼び出される A オブジェクトを指します。この動作は、メンバー関数構文 an_a_object.foo(5) を使用する場合には暗黙的に発生します。構文的には、コンパイラはこれを A::foo(&an_a_object, 5) に変換します。
コールバックの問題
元の問題に戻ると、API の Init 関数は次のことを期待しています。単一のパラメータを取る関数ポインタ。ただし、CLoggersInfra::RedundancyManagerCallBack のようなクラス メンバー関数には、本質的に、非表示の this パラメーターを含む 2 つのパラメーターが必要です。この非互換性によりコンパイル エラーが発生します。
解決策: Boost 関数または Lambda 関数を使用したバインド
従来の解決策には、Boost のブーストを使用してメンバー関数を特定のクラス インスタンスにバインドすることが含まれます。 ::bind ライブラリまたは C 11 のラムダ関数。
付きboost::bind を使用すると、非表示のこのパラメータを特定のオブジェクト インスタンスに「ロックイン」することで、必要なパラメータを受け取る新しい関数を作成できます。この新しい関数はコールバックとして渡すことができます。
#include <boost/bind.hpp> auto bound_callback = boost::bind(&CLoggersInfra::RedundencyManagerCallBack, this); Init(boost::function<void()>(bound_callback));
C 11 は、boost::bind のより簡単な代替としてラムダ関数を提供します。 Lambda 関数は this ポインターをキャプチャすることもできるため、簡潔なコールバック バインディングが可能になります:
auto lambda_callback = [this]() { RedundancyManagerCallBack(); }; Init(std::function<void()>(lambda_callback));
以上がC クラスのメンバー関数をコールバックとして渡すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。