- ベストアンサー
C++別のオブジェクトからメンバ関数をコールバック
自作のタイマオブジェクトにコールバックしたい別のオブジェクトのメンバ関数(複数)を登録して、一定時間経過後にコールバックしたいです。 今、考えているのはタイマオブジェクトでコールバック関数を呼び出す関数を仮想関数にして、継承したサブクラスごとにどのコールバック関数を呼び出すか処理を変えるやり方です。 ただ、これだと何だか複雑になりそうですし、そもそも根本的なところが間違っている気もします。 ご助言いただきたいです。 よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
No3のかたと大体同じような内容ですが、このようなパターンはObserverパターンと 言われている有名な構造で、複雑になりがちな構造ですが間違いというほどではないかと 思います。 http://ja.wikipedia.org/wiki/Observer_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3 class TimerObserver { public: virtual void onTimer() = 0; }; class Timer { public: void addObserver(TimerObserver* observer) { observers.push_back(observer); } // タイマーから一定時間ごとに呼び出されるイベント void timerEvent() { for(TimerObserver* o : observers) { o->onTimer(); } } private: vector<TimerObserver*> observers; }; 複数のオブジェクトに対応する、ということなのでこんな感じでしょうか。
その他の回答 (3)
- Tacosan
- ベストアンサー率23% (3656/15482)
よくわからんのだけど, 例えば class A { public: virtual void do_something() { /* do something */ } }; class B : public A { public: virtual void do_something() { /* do another thing */ } }; class Caller { public: Caller(A *ptr_); void do_something() { ptr->do_something(); } private: A *ptr; }; みたいなことかなぁ?
お礼
お手数おかけしました。 ご回答ありがとうございました。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
lambda と function<> 使うとか。 #include <iostream> #include <functional> #include <string> using namespace std; class callee { private: string name_; public: callee(const char* name) : name_(name) {} void callback() { cout << name_ << " are called\n"; } }; class caller { function<void(void)> callback_; public: void set_callback(const function<void(void)>& cb ) { callback_ = cb; } void call() { callback_(); } }; int main() { caller send; callee recv("recv(callee)"); send.set_callback([&recv]() { recv.callback(); }); send.call(); }
お礼
ご回答ありがとうございます。 こういったやり方もあるのですね。 大変、勉強になります。
- Tacosan
- ベストアンサー率23% (3656/15482)
オブジェクトと「メンバ関数へのポインタ」を渡しちゃいけないの?
お礼
ご回答ありがとうございます。 確かに、オブジェクトと「メンバ関数へのポインタ」を渡せば、コールバックできます。 ただ、今回は継承を使ってコールバックをしたいです。 下記の質問でNo.3の方が「クラスの継承と関数のオーバーライドで同様のことができます」と回答していますが、具体例がないため、どうやってコールバックできるのかわからないです。 コールバック関数について http://oshiete.goo.ne.jp/qa/4449389.html
お礼
ご回答ありがとうございます。 今回の質問以外でも、今まで疑問だった点が解けました。