回调函数的使用详解

实际工作中,经常使用回调函数。用来实现触发等机制,也是基于一些已开发好的底层平台,开发上层应用的常用方法。下面对回调函数做一个详细的解释。

目录

[1. 简单的回调函数实例](#1. 简单的回调函数实例)

[2. C++11,使用function<>的写法](#2. C++11,使用function<>的写法)

[3. 注册函数](#3. 注册函数)


1. 简单的回调函数实例

下面的程序,是一个非常简单的回调函数。**不要被一些复杂的声明搞退缩,实际上回调函数的使用只需要完成两个部分,一个是回调函数自身的实现,一个是调用回调函数的调用函数的实现(这里先姑且称之为调用函数)。**完成了这两个函数的实现,一套简单的回调函数流程就完成了。具体代码如下:

cpp 复制代码
#include <iostream>
using namespace std;

// 调用函数
void Use_callback(void (*callback)()){
    callback();
}

// 回调函数
void CallbackFun1(){
    cout << "callback function 1 is conducted." << endl;
}

int main(){
    Use_callback(CallbackFun1);
    return 0;
}

这里,回调函数的实现是打印"callback function 1 is conducted",调用函数是执行一次回调函数。回调函数的实现的写法和正常的函数一样,重点是调用函数的写法,与一般函数的区别是,调用函数的参数列表中,必须包含一个指向某类函数的函数指针。在上面的代码中,用void (*callback())表示。也有很多回调的使用,将函数指针单独声明出来。上述代码变为:

cpp 复制代码
#include <iostream>
using namespace std;

// 声明函数指针
typedef void (*ptrfun) ();

// 调用函数
void Use_callback(ptrfun callback){
    callback();
}

// 回调函数
void CallbackFun1(){
    cout << "callback function 1 is conducted." << endl;
}

int main(){
    Use_callback(CallbackFun1);
    return 0;
}

但本质上整个流程的实现还是只需要回调函数和调用函数两个步骤即可。需要注意,在main函数中,使用调用函数,对回调函数进行调用,将回调函数CallbackFun1作为参数传入的时候,回调函数要满足调用函数中函数指针的要求,上面代码中,这个要求就是函数返回void,函数没有参数。同时,只要满足这一要求的函数,无论函数名是什么,都可以作为参数放入调用函数中

2. C++11,使用function<>的写法

C++11中增加了function<>的写法,其实只需要替换掉函数指针的部分即可,写法如下:

cpp 复制代码
#include <iostream>
#include <functional>
using namespace std;

// 调用函数
void Use_callback (function<void()> callback){
    callback();
}

// 回调函数
void CallbackFun1(){
    cout << "callback function 1 is conducted." << endl;
}

int main(){
    Use_callback(CallbackFun1);
  

注意引用头文件functional,这里function的<>里void表示回调函数的返回类型,()里表示回调函数的参数。function<>也可以单独声明出,和前面的函数指针一样。下面来看一个带函数参数的。

cpp 复制代码
#include <iostream>
#include <functional>
#include <string>
using namespace std;

// 调用函数
void Use_callback (function<void(string)> callback, string b){
    callback(b);
}

// 回调函数
void CallbackFun1(string b){
    cout << "callback function 1 is conducted." << endl;
    cout << b << endl;

}

int main(){
    string b = "test";
    Use_callback(CallbackFun1, b);
    return 0;
}

3. 注册函数

在实际的工程中,我们往往发现没有所谓的调用函数,而是通过一个注册函数代替的。名称上的不同,体现了回调函数的另外一个重要作用,即,不是一定要调用的时候,就立刻执行回调函数,所以先把回调函数注册上,需要的时候再使用。代码如下:

cpp 复制代码
#include <iostream>
#include <functional>
#include <string>
using namespace std;

// 定义一个全局变量指针
function<void(string)> global_callback = NULL;

// 注册函数
void Register_callback (function<void(string)> callback){
    global_callback = callback;
}

int main(){
    string b = "test";

    // 回调函数
    auto f=[](string a){
        cout << "callback function 1 is conducted." << endl;
        cout << a << endl;
    };

    Register_callback(f);

    if(global_callback){
        global_callback(b);
    }
    return 0;
}

这种写法更贴近工程实际一点,首先回调函数以上面的形式写在main函数中,表示这个函数是我们自己作为应用层,自定义的函数,通过注册函数(注册函数的格式往往由更底层提供),把我们自定义的函数注册到一个全局函数指针的变量中,然后在程序需要用到的时候,调用它,传入我们定义函数时需要用到的参数

相关推荐
芯眼13 分钟前
STM32启动文件详解(重点)
java·开发语言·c++·stm32·单片机·mybatis
愚润求学41 分钟前
【Linux】动静态库链接原理
linux·运维·服务器·开发语言·笔记
呦呦彬1 小时前
【问题排查】easyexcel日志打印Empty row!
java·开发语言·log4j
Tummer83631 小时前
C#+WPF+prism+materialdesign创建工具主界面框架
开发语言·c#·wpf
九章云极AladdinEdu1 小时前
GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践
java·开发语言·人工智能·深度学习·测试工具·负载均衡·transformer
好吃的肘子1 小时前
MongoDB 应用实战
大数据·开发语言·数据库·算法·mongodb·全文检索
ghost1432 小时前
C#学习第23天:面向对象设计模式
开发语言·学习·设计模式·c#
小白学大数据2 小时前
Scrapy框架下地图爬虫的进度监控与优化策略
开发语言·爬虫·python·scrapy·数据分析
立秋67892 小时前
用Python绘制梦幻星空
开发语言·python·pygame
汉克老师2 小时前
GESP2025年3月认证C++二级( 第三部分编程题(1)等差矩阵)
c++·算法·矩阵·gesp二级·gesp2级