Java のインターフェイス セマンティクスのようなものを C++ で使用できるようにしたかったのです。最初はboost::signal
、特定のイベントに対して明示的に登録されたメンバー関数をコールバックしていました。これは本当にうまくいきました。
しかし、関数コールバックのいくつかのプールが関連していると判断し、それらを抽象化し、インスタンスの関連するすべてのコールバックを一度に登録することにしました。しかし、私が学んだことは、の特定の性質boost::bind
および/または値を取ることが、this
そのブレークを作るように見えるということでした. あるいは、メソッド宣言によって生成さadd_listener(X &x)
れるコードが変更されたという事実だけだったのかもしれません。boost::bind
問題が発生した理由は非常に大まかに理解しており、おそらく設計どおりに正しく機能していると思います。私は興味があります:代わりに何をすべきでしたか? 確かにそれを行う正しい方法があります。
コード例を次に示します。
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace std;
struct X;
struct Callback
{
virtual void add_listener(X &x) = 0;
};
struct X
{
X() {}
X(Callback &c) { c.add_listener(*this); }
virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};
struct CallbackReal : public Callback
{
virtual void add_listener(X &x)
{
f = boost::bind<void>(boost::mem_fn(&X::go), x);
}
void go() { f(); }
boost::function<void (void)> f;
};
struct Y : public X
{
Y() {}
Y(Callback &c) { c.add_listener(*this); }
virtual void go() { cout << "\t'" << __PRETTY_FUNCTION__ << "'" << endl; }
};
int main(void)
{
CallbackReal c_x;
CallbackReal c_y;
X x(c_x);
Y y(c_y);
cout << "Should be 'X'" << endl;
boost::bind<void>(boost::mem_fn(&X::go), x)();
cout << "Should be 'Y'" << endl;
boost::bind<void>(boost::mem_fn(&X::go), y)();
cout << "------------------" << endl;
cout << "Should be 'X'" << endl;
c_x.go();
cout << "I wish it were 'Y'" << endl;
c_y.go();
return 0;
}
さて、私は問題を完全に説明しませんでした。タイトルは誤解を招くものです。
ちょっと、あなた。これに反対票を投じてください。私は明らかに問題を十分に説明しておらず、最終的にはほとんどが構文エラーに帰着すると思います。:(