C++回调函数详解
首先介绍下什么是函数指针
C++函数指针
在C++中,函数指针是指向函数的指针。通过使用函数指针,我们可以把一个函数作为参数传递给另一个函数,或者把一个函数赋值给另一个指针。
定义函数指针的语法如下:
返回值类型 (*指针变量名) (参数列表);
例如,一个指向返回类型为int、参数为两个float的函数的指针可以这么定义:
int (*func_ptr)(float, float);
定义一个函数指针变量后,我们可以将其指向一个同类型的函数,例如:
int add(float x, float y) {
return (int)(x + y);
}
int main() {
int (*func_ptr)(float, float);
func_ptr = &add;
int sum = func_ptr(1.1, 2.2);
return 0;
}
在上面的代码中,我们定义了一个add函数并将其地址赋值给了一个函数指针变量func_ptr。然后我们使用这个函数指针变量来调用add函数,并把1.1和2.2作为参数传递给它。最终,sum的值将会是3。
回调函数
回调函数是指由用户实现的,用作参数传递给另一个函数的函数。在C++中,回调函数可以通过函数指针、函数对象、Lambda表达式等方式实现。
一个典型的回调函数包含两个函数,一个是函数指针的声明,另一个是被调用的函数。如下所示:
#include <iostream>
using namespace std;
// 函数指针
typedef void (*CallbackFunc)();
// 被调函数
void foo(CallbackFunc cb) {
cout << "foo" << endl;
// 调用回调函数
cb();
}
// 回调函数
void callbackFunc() {
cout << "callbackFunc" << endl;
}
int main() {
// 传递函数指针
foo(callbackFunc);
return 0;
}
在上述示例中,我们定义了一个函数指针CallbackFunc
,表示回调函数的类型,再在foo
函数中将回调函数作为参数传递,并在其中调用回调函数。
同样,我们也可以使用函数对象作为回调函数,如下所示:
#include <iostream>
#include <functional>
using namespace std;
// 被调函数
void foo(function<void()> callback) {
cout << "foo" << endl;
// 调用回调函数
callback();
}
// 回调函数
void callbackFunc() {
cout << "callbackFunc" << endl;
}
int main() {
// 传递函数对象
foo(callbackFunc);
// 传递Lambda表达式
foo([](){cout << "LambdaCallback" << endl;});
return 0;
}
在Windows平台下,HWND是一个结构体类型,用来表示一个窗口句柄。对于窗口回调函数,我们通常使用函数指针或者函数对象来实现,如下所示:
#include <windows.h>
// 窗口回调函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
// 处理消息
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow) {
// 创建窗口
HWND hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
// 注册窗口类
WNDCLASSEX wcex;
wcex.lpfnWndProc = WndProc;
// ...
}
上述代码中,我们定义了一个WndProc
函数作为窗口回调函数,用来处理各种窗口消息,比如鼠标事件、键盘事件等等。在Windows平台下,我们需要将该函数注册为窗口类的成员,并在程序运行时,通过调用CreateWindow函数来创建一个窗口。
回调函数是一种非常常用的编程模式,在各种GUI库、网络库、事件处理库等地方都有广泛应用。