当前位置: 首页 > news >正文

【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表达式。


相关文章:

  • iview组件库:关于分页组件的使用与注意点
  • Spring Boot 分层架构与数据流转详解
  • uniapp的请求封装,如何避免重复提交请求
  • php利用createSheet生成excel表格(控制行高列宽、文本自动换行及表头字体样式)
  • RestClient
  • 基于数字孪生的水厂可视化平台建设:架构与实践
  • 【python深度学习】Day 50 预训练模型+CBAM模块
  • Lighttpd 配置选项介绍
  • mysql教程笔记(四)-锁和innoDB存储引擎
  • 基于FPGA的PID算法学习———实现PI比例控制算法
  • 深度学习——简介
  • 【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
  • Vim 列操作命令完整学习笔记
  • EtherCAT 转 CANopen 网关与伺服器在配置软件上的配置步骤
  • 如何使用java把文件转成十六进制字符串
  • mybatisplus.BaseMapper#selectPage 使用方法
  • GO 语言中的flag包--易懂解释
  • 逆向工程:破解某金融App加密协议——在安全与法律的钢丝绳上行走
  • 常用数组方法、字符串方法、数组 ↔ 字符串 的转换、TS类型提示 (大全)
  • i++与++i的区别
  • 哪个网站可以做化学实验/seo零基础入门教程
  • 柳州门户网站建设公司排名/公众号如何推广引流
  • 网站做qq微信微博登录/小程序开发系统
  • 嘉兴网站建设系统/考研培训
  • 做钢化膜网站/百度网址大全旧版安装
  • 温州做外贸网站/加强服务保障 满足群众急需需求