介紹一種利用function和bind來實現回調的功能。
C++參考手冊中對function的介紹:
std::function的實例能存儲、復制及調用任何可調用的目標,包括:函數、lambda表達式、bind表達式或其他函數對象以及指向成員函數指針和指向數據成員指針,std::function包含在functional頭文件中。
我的理解是當你定義一個function對象時,你是為了用這個對象來存儲一個函數指針,在你賦值時,函數本身並不會被調用,直到你需要時,通過調用這個function對象來實現對函數的回調。
std::bind原型為:
/*unspecified*/ bind( F&& f, Args&&... args );
void f(int n1, int n2, int n3) { std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << '\n'; }
int main()
{
//生成函數對象,其中只給n1賦值,n2和n3用占位符表示。
auto fun=std::bind(f,1,std::placeholders::_2,std::placeholders::_3);
//bind已給n1賦值,所以這里調用在賦值100是無效的,輸出為:1 4 5。
fun(100,4,5);
}
下面說明如何使用function實現回調。
(1)定義回調函數類型
typedef std::function<void(int,const char *)>MessageFun; //無返回值,有一個int型參數和一個const char *型參數
(2)定義函數對象
class ThreadObject
{
public:
ThreadObject()
{
m_MessageEvent=NULL;
}
void setMessageEvent(MessageFun event)
{
m_MessageEvent=event;
}
private:
MessageFun m_MessageEvent;
void run();
}
(3)調用函數對象
void ThreadObject::run()
{
//執行任務
...
//執行完畢調用函數對象通知
if(m_MessageEvent)
m_MessageEvent(1,"Ok");
}
(4)在主線程中定義回調函數處理函數
class MainObject
{
public:
MainObject();
private:
ThreadObject m_thread;
void onMessageEvent(int status,const char *msg);
}
(5)實現回調函數處理
void MainObject::onMessageEvent(int status,const char *msg)
{
if(status==1)
cout<<msg;
}
(6)設置回調函數
MainObject::MainObject()
{
m_thread.setMessageEvent(std::bind(&MainObject::onMessageEvent,this,std::placeholders::_1,std::placeholders::_2));
}