我們的日常開發中會發現有時候使用回調函數能方便的提高程序兼容性和擴展性,那么具體回調函數怎么使用呢,下面做個筆記,有不正確的地方,歡迎指出。
一、C語言中的使用方法
首先使用回調函數,就會用到怎么注冊回調函數這個問題。你需要告訴底層代碼,它需要調用的函數是什么。那么就得事先定義好回調函數的類型。
如:
typedef void (*eventHandler_f) (int param);
然后定義實現你的注冊函數。注冊函數的作用就是告訴底層代碼,使用者想讓你調用的函數是那個
#define MAX_ID 3
static eventHandler_f eventHandlerCallbakc[MAX_ID] = {NULL, NULL, NULL};
int registerEventHandle(int id, eventHandler_f eventHandler);
int registerEventHandle(int id, eventHandler_f eventHandler)
{
if (id > MAX_ID) {
return -1;
}
eventHandlerCallback[id] = eventHandler;
return 1;
}
注冊函數也提供給使用者了,那么使用者只需要按照定義好的回調函數類型定義自己功能,然后使用注冊函數注冊就ok了。
例如:
static void printData(int data) { printf("print data [%d]", data); }
registerEventHandle(0, printData);
那么我們已經提供給了對方注冊回調的函數,對方也已經注冊他需要我們處理調用的功能函數了,那么我們怎么去使用這個回調函數呢?很簡單,就像普通的調用就可以了
例如:
Int updateData(int data) { //假如達到某些你需要的條件,然后更新數據 int parm = data; for(int i = 0; i < MAX_ID; i++) { if (eventHandlerCallback[i] != NULL) { eventHandlerCallback(data); } } }
二、C++中使用回調函數的方法
使用步驟和上面C中的過程類似,下面簡單舉例說明一下。
定義回調函數類型
#include <tr1/functional> typedef std::tr1::function <int (int value)>eventHandler_f;
定義實現注冊函數
#define MAX_ID 3 static eventHandler_f eventHandlerCallbakc[MAX_ID] = {NULL, NULL, NULL}; void registerEventHandler(eventHandler_f eventHandler); void registerEventHandler(int id, eventHandlerCallback eventHandler) { if (id > MAX_ID) { return -1; } eventHandlerCallback[i] = eventHandler;
return 1; }
使用注冊回調函數設置回調
using namespace std::tr1::placeholders; //一定要使用這個命名空間,不然編譯不過 int printData(int data) { cout<<"printf data [%d]\n"<<data; return 1; } registerEventHandler(std::tr1::bind(&printData, _1));
那么我們已經提供給了對方注冊回調的函數,對方也已經注冊他需要我們處理調用的功能函數了,接下來怎樣去調用它,就像上面C中的一樣使用就ok了
好了,簡單的回調函數使用就說到這了,有不對的地方,請指正。