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

回调函数基本实现

回调函数(Callback Function)是一段可以在将来某个时间点被调用的代码。
它通常作为参数传递给另一个函数(称为高阶函数或接受函数),并在需要的时候(比如某个操作完成或事件发生时)由那个函数来调用。

基本思想:“不要返回我结果,当你有结果时,请调用这个函数,并将结果作为参数传递给它。”

回调函数的作用

  1. 异步编程:在需要等待的操作(如文件读写、网络请求等)完成时,回调函数允许程序继续执行其他任务,而不是阻塞等待。当操作完成时,回调函数被调用,处理结果。
  2. 事件监听:在图形用户界面(GUI)编程、网络编程等领域,当发生特定事件(如用户点击按钮、接收到网络消息等)时,可以注册回调函数来响应这些事件。

使用步骤

  1. 定义回调函数类型:首先,你需要定义一个函数指针类型,该类型与你的回调函数签名相匹配。或者,你可以使用std::function,它提供了更灵活的方式来存储和调用可调用对象(包括函数、lambda表达式、bind表达式等)。
  2. 实现回调函数:然后,你需要实现一个或多个符合上述类型的函数作为回调函数。
  3. 编写接受回调作为参数的函数:接下来,编写一个函数,该函数接受一个回调函数作为参数,并在适当的时候调用它。
  4. 调用包含回调的函数:最后,将你的回调函数作为参数传递给那个函数,并在回调函数被调用时查看结果。

代码示例:

使用函数指针实现回调

#include <iostream>  
  
// 步骤1: 定义回调函数类型  
typedef void (*Callback)(int);  
  
// 步骤2: 实现回调函数  
void myCallback(int value) {  
    std::cout << "Callback called with value: " << value << std::endl;  
}  
  
// 步骤3: 编写接受回调作为参数的函数  
void doSomething(Callback cb, int value) {  
    // ... 这里可以执行一些操作 ...  
      
    // 调用回调函数  
    cb(value);  
}  
  
int main() {  
    // 步骤4: 调用包含回调的函数  
    doSomething(myCallback, 10);  
      
    return 0;  
}

使用std::function实现

#include <iostream>  
#include <functional>  
  
// 步骤1: (隐式地)定义回调函数类型  
// 这里不需要显式定义,因为std::function可以接受多种可调用对象  
  
// 步骤2: 实现回调函数  
void myCallback(int value) {  
    std::cout << "Callback called with value: " << value << std::endl;  
}  
  
// 也可以直接使用lambda表达式作为回调函数  
auto lambdaCallback = [](int value) {  
    std::cout << "Lambda callback called with value: " << value << std::endl;  
};  
  
// 步骤3: 编写接受回调作为参数的函数  
void doSomething(std::function<void(int)> cb, int value) {  
    // ... 这里可以执行一些操作 ...  
      
    // 调用回调函数  
    cb(value);  
}  
  
int main() {  
    // 步骤4: 调用包含回调的函数  
    doSomething(myCallback, 20);  
    doSomething(lambdaCallback, 30);  
      
    return 0;  
}


http://www.kler.cn/a/281686.html

相关文章:

  • 【Unity基础】对比Unity中两种粒子系统
  • 用vscode编写verilog时,如何有信号定义提示、信号定义跳转(go to definition)、模块跳转(跨文件跳转)这些功能
  • Java从入门到精通笔记篇(十三)
  • unity 打包WebGL打开后Input无法输入中文,在手机端无法调用输入法(使用WebGLInput)
  • JAVA中CountDownLatch使用方法
  • 【单片机基础】单片机的功能保护机制
  • 什么是跨域问题?出现的原因和解决方法是什么?
  • 自动化常用元素定位
  • pymysql 与 MySQL数据库交互
  • 程序员的自我修炼:如何拒绝快餐式学习,深耕技能20240829
  • windows消息机制之HMIsMarkDestroy宏定义的理解
  • c语言——数组
  • 基于my Batis优化图书管理系统(一)
  • FastAdmin 和 Dcat Admin从使用场景、适合人群、使用成本、资源完善程度、bug 解决、安全性全方位解析
  • go 系列实现websocket
  • 【数据结构-前缀异或和】力扣1371. 每个元音包含偶数次的最长子字符串
  • C#过 SemaphoreSlim 实现高效的数据库并发控制和资源管理(多线程)
  • 鸿蒙HSP,HAP,HAR
  • 基于matlab的深度学习案例及基础知识专栏前言
  • 基于imx6ull平台opencv的图像采集和显示屏LCD显示功能(不带Qt界面)
  • Android JNI开发:System.loadLibrary加载机制
  • Kubernetes:解决命名空间无法正常删除问题 —— 清空 Finalizers 字段的方法步骤
  • XDMA原理
  • beforeEach中addRoutes后使用next()无法访问,路由未生效,刷新页面白屏,使用next({ ...to, replace: true })
  • 书生大模型实战营(第3期)进阶岛第二关--Lagent 自定义你的 Agent 智能体
  • 笔记小结:《利用python进行数据分析》之使用pandas和seaborn绘图