【C++】C++回调函数基本用法(详细讲解)

请添加图片描述


👉博__主👈:米码收割机
👉技__能👈:C++/Python语言
👉公众号👈:测试开发自动化【获取源码+商业合作】
👉荣__誉👈:阿里云博客专家博主、51CTO技术博主
👉专__注👈:专注主流机器人、人工智能等相关领域的开发、测试技术。


一文详解C++回调函数


目录

  • 一文详解C++回调函数
  • 1. 什么是回调函数?
  • 2. 为什么需要回调函数
  • 3. 回调函数的应用场合
  • 4.举例说明
  • 5. 高级回调方式


1. 什么是回调函数?

回调函数可以被简单地理解为:A函数作为参数传递给B函数,然后B函数在执行的某一时刻调用A函数。这里的A函数就是回调函数。


2. 为什么需要回调函数

回调提供了一种灵活的方式来扩展或自定义函数的行为,需要在某些特定的时刻执行特定的动作,但这些动作可能因情境而异。通过使用回调,可以允许其他代码决定何时以及如何响应。


3. 回调函数的应用场合

  1. 事件驱动编程:在图形用户界面(GUI)编程中,用户的每一个动作,如点击按钮、移动鼠标等,都可能会触发一个事件。这些事件常常通过回调函数来处理。例如,当用户点击一个按钮时,你可能希望执行一个特定的函数。

  2. 异步编程:在网络编程或者其他需要异步处理的场景中,当一个长时间的操作(如网络请求)完成时,你可能希望执行某个函数。这个函数可以通过回调来指定。

  3. 定时器:某些编程环境允许你设置定时器,当定时器到期时执行一个函数。这个函数就是通过回调来指定的。

  4. 自定义排序:例如,在C++中,std::sort函数允许你传入一个回调函数来自定义排序逻辑。

  5. 遍历:如在前一个回答中所示,当你遍历一个集合并希望对每个元素执行特定操作时,可以使用回调函数。

  6. 线程或任务的回调:当你启动一个线程或提交一个任务,你可能希望在它完成时得到通知。这可以通过将回调函数传递给线程或任务来实现。

  7. 中间件和钩子:在某些框架中,你可能希望在请求处理的不同阶段插入自定义逻辑,如日志记录、验证等。这通常通过回调函数或钩子实现。

  8. 错误处理:你可以为可能出错的操作提供一个回调函数,当操作失败时,这个回调函数会被调用,并传入关于错误的信息。

  9. 数据库查询:在数据库编程中,当查询完成并返回结果时,你可以通过回调函数来处理这些结果。

  10. 动画和游戏开发:例如,当动画的某一帧完成渲染时或者游戏中某个事件发生时,你可能希望执行特定的回调函数。


4.举例说明

假设你有一个函数forEach,这个函数的任务是遍历一个整数数组,并对每个元素执行某个操作。这个“某个操作”可以通过回调函数来定义。

#include <iostream>

// 定义回调函数的类型
typedef void (*CallbackFunction)(int);

// 遍历数组,并对每个元素调用回调函数
void forEach(int* array, int size, CallbackFunction callback) {
    for (int i = 0; i < size; i++) {
        callback(array[i]);
    }
}

// 一个简单的打印函数,用作回调
void printNumber(int num) {
    std::cout << "Number: " << num << std::endl;
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    forEach(arr, 5, printNumber);  // 使用printNumber作为回调函数
    return 0;
}

代码说明

  1. 引入头文件
#include <iostream>

这行代码包含了iostream头文件,允许我们使用C++标准库中的输入输出功能,例如std::cout

  1. 定义回调函数的类型
typedef void (*CallbackFunction)(int);

这里,我们定义了一个新的数据类型CallbackFunction,它是指向一个函数的指针。这个函数接受一个int参数并返回void

  1. forEach函数定义
void forEach(int* array, int size, CallbackFunction callback) {
    for (int i = 0; i < size; i++) {
        callback(array[i]);
    }
}

这个forEach函数接受三个参数:

  • 一个整数数组array
  • 数组的大小size
  • 一个回调函数callback,它的类型为CallbackFunction

函数的功能是遍历数组,并对数组的每个元素调用回调函数callback

  1. 回调函数定义
void printNumber(int num) {
    std::cout << "Number: " << num << std::endl;
}

printNumber函数是定义的回调函数。它接受一个int参数,并将这个数字打印到控制台。

  1. main函数
int main() {
    int arr[] = {1, 2, 3, 4, 5};
    forEach(arr, 5, printNumber);  // 使用printNumber作为回调函数
    return 0;
}

main函数是程序的入口点。

首先,定义了一个包含5个整数的数组arr

然后,调用forEach函数,并将数组arr、其大小(5)以及回调函数printNumber作为参数传递给它。

forEach函数执行时,它会遍历数组的每个元素,并对每个元素调用printNumber函数。因此,输出将是:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

这个例子演示了如何在C++中定义和使用回调函数。定义了一个forEach函数,它接受一个数组和一个回调函数作为参数,并对数组的每个元素调用回调函数。


5. 高级回调方式

在现代C++中,我们经常使用函数对象、lambda函数和std::function来实现更灵活的回调。

例如,使用lambda表达式:


#include <iostream>
#include <vector>
#include <functional>

void forEach(const std::vector<int>& numbers, const std::function<void(int)>& callback) {
    for (int num : numbers) {
        callback(num);
    }
}

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    forEach(numbers, [](int num) {
        std::cout << "Number: " << num << std::endl;
    });
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/66233.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL: Failed to Connect to MySQL at XXXX:3306 with user root

客户端连接MySQL服务器&#xff0c;报错&#xff1a; 解决方案&#xff1a; 没有让root用户远程登录&#xff0c;需要设置&#xff1b; 进入MySQL服务器&#xff0c;修改一下 # mysql -h localhost -uroot -P3306 -p12345678 mysql: [Warning] Using a password on the comm…

基于Java的新闻全文搜索引擎的设计与实现

中文摘要 本文以学术研究为目的&#xff0c;针对新闻行业迫切需求和全文搜索引擎技术的优越性&#xff0c;设计并实现了一个针对新闻领域的全文搜索引擎。该搜索引擎通过Scrapy网络爬虫工具获取新闻页面&#xff0c;将新闻内容存储在分布式存储系统HBase中&#xff0c;并利用倒…

【UE4 RTS】01-Camera SetUp

UE版本&#xff1a;4.24.3 前言 本篇主要完成游戏模式、玩家控制器和玩家控制的Pawn的设置&#xff0c;下一篇介绍如何实现Pawn的移动 步骤 1. 首先创建一个俯视角游戏模板 2. 首先删除“TopDownCharacter”&#xff0c; 3. 新建一个文件夹命名为“RTS_Toturial” 在文件夹…

adb 命令行执行单元测试

文章目录 1、配置 adb 环境变量2、adb 执行测试3、官方文档解读 adb 使用&#xff08;1&#xff09;第一条执行测试的adb命令&#xff08;2&#xff09;am instrument 参数&#xff08;3&#xff09;-e 参数 的 key-value键值对&#xff08;4&#xff09;用法用例 4、存在问题 …

SpringBoot系列---【三种启动传参方式的区别】

三种启动传参方式的区别 1.三种方式分别是什么? idea中经常看到下面三种启动传参方式 优先级 Program arguments > VM options > Environment variable > 系统默认值 2.参数说明 2.1、VM options VM options其实就是我们在程序中需要的运行时环境变量&#xff0c;它需…

ArcGIS Pro基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合、案例应用全流程科研能力提升

目录 第一章 入门篇 GIS理论及ArcGIS Pro基础 第二章 基础篇 ArcGIS数据管理与转换 第三章 数据编辑与查询、拓扑检查 第四章 制图篇 地图符号与版面设计 第五章 空间分析篇 ArcGIS矢量空间分析及应用 第六章 ArcGIS栅格空间分析及应用 第七章 影像篇 遥感影像处理 第八…

激活函数总结(二):ELU、SELU、GELU激活函数

激活函数总结&#xff08;二&#xff09;&#xff1a;ELU、SELU、GELU激活函数 1 引言2. 激活函数2.1 ELU&#xff08;Exponential Linear Unit&#xff09;激活函数2.2 SELU&#xff08;Scaled Exponential Linear Unit&#xff09;激活函数2.3 GELU激活函数 3. 总结 1 引言 …

UI自动化测试之Jenkins配置

背景&#xff1a; 团队下半年的目标之一是实现自动化测试&#xff0c;这里要吐槽一下&#xff0c;之前开发的测试平台了&#xff0c;最初的目的是用来做接口自动化测试和性能测试&#xff0c;但由于各种原因&#xff0c;接口自动化测试那部分功能整个废弃掉了&#xff0c;其中…

深度学习,计算机视觉任务

目录 计算机视觉任务 1.K近邻算法 2.得分函数 3.损失函数的作用 4.向前传播整体流程 5.反向传播计算方法 计算机视觉任务 机器学习的流程&#xff1a; 数据获取 特征工程 建立模型 评估与应用 计算机视觉&#xff1a; 图像表示&#xff1a;计算机眼中的图像&#…

HCIA---路由器--静态路由

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.路由器简介 路由器是一种网络设备&#xff0c;用于将数据包从一个网络发送到另一个网络…

python基础3——流程控制

文章目录 一、操作符1.1 比较操作符1.2 逻辑操作符1.3 成员操作符1.4 身份操作符 二、流程控制2.1 条件判断2.2 循环语句2.2.1 for循环2.2.2 while循环 2.3 continue与break语句2.4 文件操作函数 三、函数3.1 定义函数3.2 作用域3.3 闭包3.4 函数装饰器3.5 内建函数 一、操作符…

stm32与上位机电脑间最快的通信方式是什么?

对于小型多关节机械臂的控制电路设计&#xff0c;选择合适的通信方式可以提高MCU与上位机之间的实时性。以下是一些在STM32上常用的通信方式&#xff0c;你可以根据你的具体需求选择适合的&#xff1a; 串口通信&#xff08;UART&#xff09;&#xff1a;串口通信是一种常见的…

Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

目录 一、SpringBootApplication 二、SpringBootConfiguration 三、EnableAutoConfiguration 四、ComponentScan 一、SpringBootApplication SpringBootApplication是Spring Boot框架的核心注解之一&#xff0c;它用于标识一个主配置类&#xff0c;通常是项目的入口类。该…

selenium常见等待机制及其特点和使用方法

目录 1、强制等待 2、隐式等待 3、显式等待 1、强制等待 强制等待是在程序中直接调用Thread.sleep(timeout) ,来完成的&#xff0c;该用法的优点是使用起来方便&#xff0c;语法也比较简单&#xff0c;缺点就是需要强制等待固定的时间&#xff0c;可能会造成测试的时间过…

诺瓦星云面试汇总

1、C语言向一个内存地址写值&#xff0c; int main() {int value 42;int *ptr (int *)0x12345678; // Replace with the desired memory address*ptr value 2、申请释放内存 申请内存int *dynamicArray (int*)malloc(size *sizeof(int));释放内存 free(dynamicArray)…

网络编程——MAC地址、IP地址和子网掩码

MAC地址、IP地址和子网掩码 一、MAC地址&#xff1a;硬件身份证 1、MAC地址的概念 MAC地址&#xff0c;即媒体访问控制地址&#xff08;Media Access Control Address&#xff09;&#xff0c;是一个用于唯一标识网络设备的物理地址。每个网络接口卡&#xff08;NIC&#xf…

go错误集(持续更新)

1.提示以下报错 Build Error: go build -o c:\Users\Administrator\Desktop__debug_bin2343731882.exe -gcflags all-N -l . go: go.mod file not found in current directory or any parent directory; see ‘go help modules’ (exit status 1) 解决办法&#xff1a; go …

Android Framework底层原理之WMS的启动流程

一 概述 今天&#xff0c;我们介绍 WindowManagerService&#xff08;后续简称 WMS&#xff09;的启动流程&#xff0c;WMS 是 Android 系统中&#xff0c;负责窗口显示的的服务。在 Android 中它也起着承上启下的作用。 如下图&#xff0c;就是《深入理解 Android》书籍中的…

《Kali渗透基础》14. 无线渗透(四)

kali渗透 1&#xff1a;相关工具1.1&#xff1a;Aircrack-ng1.1.1&#xff1a;airmon-ng1.1.2&#xff1a;airodump-ng1.1.3&#xff1a;aireplay-ng1.1.4&#xff1a;airolib-ng1.1.5&#xff1a;bessid-ng 1.2&#xff1a;JTR1.3&#xff1a;Evil Twin Attacker1.4&#xff1…

clickhouse调研报告2

由Distributed表发送分片数据 clickhouse分区目录合并 clickhouse副本协同流程 clickhouse索引查询逻辑 clickhouse一级索引生成逻辑(两主键) clickhouse的data目录下包含如下目录: [root@brfs-stress-01 201403_10_10_0]# ll /data01/clickhouse/data total 4 drwxr-x---…