古早 C++ 的 Callback 實作一般是這樣的。
class Callback
{
virtual void handler( int event );
};
class SourceClass
{
void func()
{
if (cb_ != NULL)
cb_->handler( 123 );
}
void set_callback( Callback* callback )
{
cb_ = callback;
}
Callback* cb_;
};
class ListenerClass
{
class MyCallback : public Callback()
{
void handler( int event ) override
{
// handle the event (123) from SourceClass
}
};
ListenerClass()
{
src_object_.set_callback( new MyCallback() );
}
SourceClass src_object_;
};
也就是把 Callback 做成一個 Class (i.e. Class Callback),然後再做一個繼承該 Callback 的物件 (i.e. Class ListenerClass::MyCallback) 裡面自己實作要如何處理 Callback 回傳的訊息,最後用個 Pointer 傳到底層 (i.e. Class SourceClass) 去讓底層使用。
這做法沒甚麼問題,Java 也是這樣做的,但是就是寫 code 很麻煩,為了一個 Callback 還要建立另外二個 Class。
後來 C++11 加了新的做法,對我來說就是把 C 的 function pointer 拿來改進,讓 Class Member 也能當作 function pointer 使用。
class SourceClass
{
void func()
{
if (cb_ != nullptr)
cb_( 123 );
}
void set_callback(std::function<void(int)> callback)
{
cb_ = callback;
}
std::function<void(int)> cb_;
};
class ListenerClass
{
ListenerClass()
{
auto cb_func = std::bind(
&ListenerClass::handler,
this,
std::placeholders::_1);
src_object_.set_callback( cb_func );
}
void handler( int event )
{
// handle event 123 here
}
SourceClass src_object_;
}
C++11 的做法在架構上精簡了很多,少了二個中間的 Class 宣告看起來清楚多了。