【C++】回调函数,是什么,怎么用?
1. 什么是回调函数?
**回调函数(Callback)**就是:
你把一个函数的地址(指针/对象),传给另一个函数或对象,对方在“合适的时机”来调用它。
- 本质是“把处理权交出去”。
- 这样可以实现灵活的扩展/事件驱动/异步机制。
2. 回调函数的本质
- C语言时代:就是传递一个函数指针。
- C++时代:不仅可以用普通函数指针,还可以用函数对象(仿函数)、lambda表达式、
std::function
等现代写法,适配性更强。
3. 最简单的例子(C风格)
// 定义一个“回调”类型
typedef void (*CallbackFunc)(int);void runCallback(CallbackFunc cb) {cb(42); // 调用传入的回调函数
}// 一个实际的处理函数
void myHandler(int x) {printf("Hello, callback! x=%d\n", x);
}int main() {runCallback(myHandler); // 把myHandler当作回调传进去return 0;
}
- myHandler 就是回调。
- runCallback 不关心你实现了什么,只知道该时候就帮你调用。
4. C++ 现代写法(std::function)
#include <functional>
#include <iostream>void test(std::function<void(int)> cb) {cb(123);
}int main() {// 普通函数auto f = [](int x){ std::cout << "callback x=" << x << std::endl; };test(f);// 直接用lambdatest([](int x){ std::cout << "hello " << x << std::endl; });return 0;
}
std::function
允许传递任何可调用对象(普通函数、lambda、成员函数绑定等),极大扩展了灵活性。
5. 回调常见应用场景
- 事件驱动:比如“按钮被点击时通知你”,“串口收到数据后调用你的处理函数”。
- 自定义处理:算法库里,让用户自定义“排序条件”、“数据过滤方式”等。
- 异步操作:定时器、网络、IO等。
6. 成员函数/对象回调
有时你要“回调到类的成员函数”怎么办?
答:用std::bind
或者lambda捕获。
#include <functional>
#include <iostream>class Foo {
public:void onEvent(int x) { std::cout << "Foo::onEvent " << x << std::endl; }
};void test(std::function<void(int)> cb) {cb(77);
}int main() {Foo foo;test(std::bind(&Foo::onEvent, &foo, std::placeholders::_1));// 或者lambdatest([&foo](int x){ foo.onEvent(x); });return 0;
}
7. 例如:和协议代码的结合(函数指针做事件回调)
// 声明
typedef void (ReceiveDataEvent)(std::vector<SFramePacket>*);// 类里
ReceiveDataEvent* OnReceiveData;// 触发
if(OnReceiveData != nullptr) {OnReceiveData(&mReceivedPacketMonitorBuffer);
}
- 这就是最经典的C/C++回调模式:先
SetOnReceiveDataEvent
注册你的回调,数据到时就会帮你自动调用!
8. 小结
回调函数就是你把“处理权”交出去,对方在需要时再“回调”你,实现灵活的模块解耦。C++既支持C风格函数指针,也支持更强大的
std::function
和lambda表达式。