C++回調函數


我們經常會把一些耗時的操作放到線程中去執行,當任務執行完畢后就需要通知主線程,通知的方式有很多,在windows平台上可以使用消息機制,如果不想依賴平台API,讓代碼具有良好移植性,使用回調函數也是一種方法。

(1)定義函數指針類型

typedef void(*pResult)(int);

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

private:

  pResult m_ResultEvent;

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

void setResultEvent(pResult event)

{

  m_ResultEvent=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來實現。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM