您的位置:首页 > 其它

回调函数概念与示例

2014-05-30 11:14 211 查看
回调函数机制:

(1)定义一个回调函数

(2)提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者

(3)当特定事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理

简单来说,回调函数就是调用者通过函数指针调用的函数,也就是说把函数指针作为参数传递给另一个函数,并用来调用它指向的函数时,这个以此函数指针为参数的函数就称为回调函数。

举个例子

#include <iostream>
#include <cstring>
using namespace std;

typedef void (*FP)(char* s);   //以char*为参数的函数指针类型为FP
//三种不同函数
void f1(char* s){ cout << "f1方法: " << s << endl; }
void f2(char* s){ cout << "f2方法: " << s << endl; }
void f3(char* s){ cout << "f3方法: " << s << endl; }

class CallBack
{
public:
char* s;
CallBack(){ s = nullptr; }
CallBack(char* tmp)
{
int len = strlen(tmp) + 1;
s = new char[len];
strcpy_s(s, len, tmp);
}
void CallF(FP fp)  //回调函数,调用FP类型的指针
{
fp(s);
}
~CallBack()
{
if (s != nullptr)
delete s;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
CallBack obj("hello");

//模拟事件
obj.CallF(f1);
obj.CallF(f2);
obj.CallF(f3);

return 0;
}


可以看出,回调函数不关心谁是调用者,只关心被调用函数是什么。

现在回顾回调函数的概念主要是由于看到win32程序里窗口函数都被设计成了Callback函数,因为很多时候操作系统也要调用你的窗口函数,所以窗口函数设计为callback形式开放一个接口给操作系统调用。

用上面一段代码CallF能调用一堆FP类型的函数,有时候需要根据调用者类型来安排被调用函数。

而在win32程序里消息映射里则是类似这样的一个机制

struct MSGMAP_ENTRY
{
UINT nMessage;
LONG (*pfn)(HWND, UINT, WPARAM, LPARAM);
};//消息与处理例程的对照表格
struct MSGMAP_ENTRY _messageEntries[] =
{
WM_CREATE, OnCreate,
WM_PAINT,  OnPaint,
WM_SIZE,   OnSize,
WM_COMMAND, OnCommand.
WM_CLOSE,  OnClose,
WM_DESTROY, OnDestroy
};

#define dim(x) (sizeof(x) / sizeof(x[0]))

//于是窗口函数可以这么设计
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
for (int i = 0; i < dim(_messageEntris); i++)
{
if (message == _messageEntries[i].nMessage)
{
return ((*_messageEntries[i].pfn)(hWnd, message, wParam, lParam));
}
}
}


当系统接收到相应消息时,可以通过nMessage来判断fpn,也就是要调用的函数,并执行它,这就是回调函数了。

就像最初那段代码我可以定义为char* s为某类型字符串时时调用f1函数,另一类型字符串时调用f2函数,等等。

其实也就是设计模式中的策略模式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: