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

C++ 回调函数学习笔记(从入门到理解)

一、什么是回调函数(Callback)

1. 一句话理解

把一个函数“交给别人”,在合适的时候由别人调用,这就是回调。

你写函数,不自己主动调,而是让别人帮你在某个时机执行。


二、生活中的理解

外卖例子

你点外卖时:

你对平台说:

到了给我打电话。

这个“打电话”动作就是你提供的回调函数

  • 你不需要一直问外卖到了没

  • 外卖到了平台会主动调用你留的“通知函数”


三、本质定义

回调 =函数指针 / 可调用对象+被其他函数调用

公式:

把函数A作为参数 传给函数B 由函数B在某个时机调用函数A

A:回调函数
B:触发回调的函数


四、最基础回调(函数指针)

示例1

#include <iostream> using namespace std; void hello() { cout << "我是回调函数" << endl; } void execute(void (*cb)()) { cout << "先做自己的事..." << endl; cb(); // 调用回调 } int main() { execute(hello); }

输出

先做自己的事... 我是回调函数

分析

这个:

void (*cb)()

是函数指针。

意思:

cb 是一个指针 指向参数为空 返回void的函数

拆开理解

普通函数:

void hello();

函数指针:

void (*p)();

赋值:

p = hello;

调用:

p();

图解

hello ---> 函数地址 ↓ p ↓ p();

五、带参数回调

#include <iostream> using namespace std; void printSum(int a,int b) { cout<<a+b<<endl; } void calc(void (*cb)(int,int)) { cb(3,5); } int main() { calc(printSum); }

8

六、为什么需要回调

不用回调

任务完成 然后自己主动去检查

轮询(低效)


用回调

任务完成 系统自动通知你

事件驱动(高效)


常见场景

按钮点击

Qt:

connect(button, &QPushButton::clicked, this, &MainWindow::onClick);

点击按钮:

onClick()

就是回调。


七、C风格回调(函数指针)

经典写法:

void doWork(void (*callback)()) //void (*callback)()是一个函数函数指针 { //任务完成 callback(); }

优点:

  • 简单

缺点:

  • 只能传普通函数

  • 不灵活


八、C++现代回调 std::function

这个比函数指针高级很多。


头文件

#include <functional>

写法

function<void()>

意思:

返回 void 参数为空 可调用对象

示例

#include <iostream> #include <functional> using namespace std; void test() { cout<<"hello"<<endl; } void run(function<void()> cb) { cb(); } int main() { run(test); }

和函数指针对比

函数指针:

void (*cb)()

现代写法:

function<void()> cb

更像:

装任何能调用的东西的容器

九、function 能装什么


1 普通函数

run(test);

2 Lambda

run([](){ cout<<"lambda"; });

3 仿函数

class Functor { public: void operator()() { cout<<"仿函数"; } }; run(Functor());

三者都能回调

普通函数 Lambda 函数对象

这就是现代 C++ 强大之处。


十、Lambda做回调(最常用)

#include <iostream> using namespace std; void work(function<void()> cb) { cout<<"处理中..."<<endl; cb(); } int main() { work([](){ cout<<"处理完成"; }); }

输出

处理中... 处理完成

十一、带状态的回调

函数指针做不到:

我要回调还能带变量

Lambda可以:

int x=10; auto cb=[x]() { cout<<x; };

输出

10

这叫:捕获变量


十二、异步回调思想

下载文件 下载完通知我

伪代码:

download(url, [](){ cout<<"下载完成"; });

是不是很像:

事件发生 触发回调

十三、回调本质图

你写函数 ↓ 交给系统 ↓ 事件发生 ↓ 系统调用你的函数

就是回调。


十四、回调 vs 普通函数调用

普通调用

main └── hello()

你主动调。


回调

main └── system └── hello()

系统替你调。


十五、回调常见面试题


Q1 什么是回调

答:

将函数作为参数传递 由其他函数在特定时机调用

Q2 回调实现方式

  • 函数指针

  • std::function

  • lambda

  • 仿函数

  • 成员函数绑定


Q3 函数指针和function区别

对比函数指针std::function
普通函数支持支持
lambda有限支持
仿函数不方便支持
灵活性
现代C++较少常用

结论:

现代开发优先 std::function

十六、手写一个回调框架

#include <iostream> #include <functional> using namespace std; class Task { private: function<void()> callback; public: void setCallback(function<void()> cb) { callback=cb; } void run() { cout<<"任务执行中..."<<endl; if(callback) callback(); } }; int main() { Task t; t.setCallback([](){ cout<<"任务完成回调"; }); t.run(); }

输出

任务执行中... 任务完成回调

十八、记忆口诀

自己调用叫函数调用 别人调用叫回调

十九、⭐核心代码模板⭐

传统函数指针模板

void callback() { } void run(void (*cb)()) { cb(); } int main() { run(callback); }

现代模板

#include <functional> using namespace std; void run(function<void()> cb) { cb(); } int main() { run([](){ }); }

二十、容易混淆的几个概念

回调 vs 函数指针

不是一个东西。

函数指针只是:

实现回调的一种方式

回调 vs Lambda

Lambda不是回调。

Lambda可以作为回调

回调 vs 异步

不是一回事:

  • 异步常用回调通知结果

  • 回调不一定异步


二十一、总结

回调本质

把函数交出去 让别人以后调用

实现方式

函数指针 std::function lambda 仿函数

现代推荐:

std::function + lambda

二十二、最后一句理解回调

不是我去调用函数 而是我把函数留给系统 等系统回来调用我

这就是回调。

http://www.jsqmd.com/news/725761/

相关文章:

  • 2026年法学论文降AI工具推荐:法律研究和司法实践部分降AI方案 - 还在做实验的师兄
  • 【三甲医院已验证】:Dify+本地化医疗术语本体库+动态权限沙箱——实现患者数据“查得准、问不泄、审得清”的4层隔离架构
  • 2026年日本九州再生医疗靠谱服务商选型指南与正规合作机构推荐 - 商业小白条
  • 2026年九州再生医疗代表处对接机构推荐:日本再生医疗服务选型参考 - 商业小白条
  • 2026年日本跨境医疗服务机构推荐:核心能力梳理与高适配合作机构选择指南 - 商业小白条
  • 别再死记硬背Cypher语法了!用这个电商用户购买图谱实战,5分钟搞定Neo4j增删改查
  • 夜神模拟器+Postern+Charles+BurpSuite:手把手教你搭建安卓抓包测试环境(保姆级避坑)
  • 直播系统源码开发必备:美颜SDK技术与商业价值解析
  • 福州专业美容机构推荐,技术手法服务全在线 - 品牌2026
  • 浏览器渲染层技术革命:kill-doc如何重新定义文档下载体验
  • 豆包生成的图片带有AI字样怎么去除?
  • 2026年5月亨得利中国区售后服务网络优化升级(最新电话及地址)【重磅推荐亲测填坑】 - 亨得利官方服务中心
  • 广东毫米级精密加工厂家排行:5家实力实体盘点 - 奔跑123
  • 音乐API终极指南:如何快速获取全网音乐播放地址
  • 2026 物流空域资源管理无人机低空平台推荐,冰柏科技这样解决 - 品牌2026
  • 告别CNN!用BERT的思路搞定加密流量分类:PERT实战与PyTorch代码解析
  • 2026折叠屏扩产潮,手机铰链夹爪供应商深度推荐 - 品牌2026
  • 珠海平价美食合集|人均50-100,九龙饭店性价比封神 - 奔跑123
  • 赢下北美市场,追觅洗地机的「新中式解法」
  • 上海乐时宜实业:奉贤工字钢批发找哪家 - LYL仔仔
  • 避坑指南:搞定IP5306_I2C轻载关断和NU1680线圈匹配的常见问题
  • 选购涡街流量计不踩坑,靠谱品牌排行榜 - 陈工日常
  • GEO优化靠谱公司有哪些?2026别瞎选! - FaiscoJeff
  • Windows平台安卓应用无缝安装方案:APK Installer技术实践
  • 福州靠谱生活美容院推荐,专业高性价比还口碑出众 - 品牌2026
  • 【模板】整数域二分【牛客tracker 每日一题】
  • 2026 国内最新靠谱的推拉窗推荐!广东佛山优质厂家榜单发布,靠谱 - 十大品牌榜
  • 云之家“待审批”存在任务,与ERP不同步
  • Laravel Octane × AI Workers高并发崩溃真相:Event Loop阻塞、内存泄漏与PHP-FPM回退策略(附12个真实core dump分析截图)
  • 微信立减金回收平台推荐:正规、安全、有保障! - 团团收购物卡回收