C++回調函數

咱們常常會把一些耗時的操做放到線程中去執行,當任務執行完畢後就須要通知主線程,通知的方式有不少,在windows平臺上能夠使用消息機制,若是不想依賴平臺API,讓代碼具備良好移植性,使用回調函數也是一種方法。windows

(1)定義函數指針類型函數

typedef void(*pResult)(int);this

(2)在類的內部定義一個函數指針對象線程

private:指針

  pResult m_ResultEvent;對象

(3)添加一個函數用來指定回調函數繼承

void setResultEvent(pResult event)回調函數

{io

  m_ResultEvent=event;event

}

 

(4)在線程任務完成後回調函數通知主線程

void run()

{

     //do something

  if(m_ResultEvent)

    m_ResultEvent(1);

}

(5)在主線程中定義回調處理函數

須要注意的是函數只能定義爲靜態函數,只有全局函數或靜態函數才能做爲函數指針傳遞。

class MainObject

{

public:

  MainObject();

private:

       ThreadObject m_Thread;

  int m_Status;

  static void doResult(int status);

}

MainObject::MainObject()

{

  m_Thread.setResultEvent(doResult);
}

這樣回調的功能就基本實現了。可是若是回調函數只能傳靜態函數,那麼在回調函數中如何與實際的對象聯繫呢。

咱們能夠把對象做爲回調函數的一個參數,這樣經過調用這個參數就能夠實現對此對象的訪問了。能夠將上面的回調函數作一下改造。

typedef void(*pResult)(const void *p,int);

修改線程設置函數,傳入對象指針,並保存

private:

void * m_Object;

void setResultEvent(void *p,pResult event)

{

  m_ResultEvent=event;

  m_Object=p;

}

在調用的時候將對象this指針傳入:

MainObject::MainObject()

{

  m_Thread.setResultEvent(this,doResult);
}

 

//將對象指針做爲參數傳入回調函數中

void run()

{

     //do something

  if(m_ResultEvent)

    m_ResultEvent(m_Object,1);

}

//在處理函數中將void*指針強轉爲須要的對象類型:

void MainObject::doResult(const void *p,int status)

{

  MainObject *obj=(MainObject *)p;

  obj->m_Status=status;

}

以上就是C++中對象回調通知的方式,回調函數主要使用了函數指針的概念,實際在C語言中就已存在,C++繼承了這種機制,可是因爲函數只能傳入靜態的或全局的,因此封裝性並很差,類型強制轉換也顯得繁瑣。在C++中有新的機制能夠實現類似的功能,就是利用std::function和std::bind來實現。

相關文章
相關標籤/搜索