一.回调函数介绍

1.概念

回调函数是一种在程序运行期间通过函数指针调用的函数,它通常用于实现事件驱动、异步通信、消息传递等功能。

在回调函数中,被调用的函数通常称为回调函数(Callback Function),而调用回调函数的函数通常称为回调函数容器(Callback Container)。回调函数容器可以在满足某些条件或事件发生时调用回调函数,以便执行相应的操作。

2.为什么需要回调函数

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

3. 回调函数的应用场合

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

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

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

二.C语言风格实现

1.应用示例

#include "mainwindow.h"

#include <QApplication>

// 定义回调函数的类型

typedef void (*CallbackFunction)(int);

typedef struct {

    CallbackFunction userCallbackFunc;

    int index;

}Device_t;

//回调应用

Device_t device;

// 遍历数组,并对每个元素调用回调函数

void forEach(int* array, int size, CallbackFunction callback) {

    for (int i = 0; i < size; i++) {

        callback(array[i]);

    }

    device.userCallbackFunc = callback;

    qDebug()<<"forEach end";

}

// 一个简单的打印函数,用作回调 //可以和库分离定义

void printNumber(int num) {

    qDebug() << "Number: " << num ;

}

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    

    int arr[] = {1, 2, 3, 4, 5};

    forEach(arr, 5, printNumber);

    device.userCallbackFunc(7);

    

    

    return 0;

}

2.输出结果:

C++与Qt中回调函数的两种实现方法-LMLPHP

二.C++风格实现

1.介绍

std::function是一个函数模板类,包含在#include <functional> 中。

到了C++11以后在标准库里引入了std::function模板类,这个模板概括了函数指针的概念。函数指针只能指向一个函数,而std::function对象可以代表任何可以调用的对象,

包括函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针,它是对 C++ 中现有的可调用实体的一种类型安全的包装。

2.std::function的语法

std::function<return_type(args_type)>

return_type是函数的返回值,括号内就是参数的类型

举个例子,刚才定义的是一个返回值是void,带两个int的参数的函数指针,它使用std::function就如下表示:

std::function<void(int ,int)> func;

3.代码示例

#include "mainwindow.h"

#include <QApplication>

// 定义回调函数的类型

typedef std::function<int(int)> Functor;;

typedef struct {

    Functor userCallbackFunc;

    int index;

}Device_t;

//应用:

Device_t device;

// 遍历数组,并对每个元素调用回调函数

void forEach(int* array, int size, Functor callback) {

    for (int i = 0; i < size; i++) {

        callback(array[i]);

    }

    device.userCallbackFunc = callback;

    qDebug()<<"forEach end";

}

// 一个简单的打印函数,用作回调

int printNumber(int num) {

    qDebug() << "Number: " << num ;

}

int main(int argc, char *argv[])

{

    QApplication a(argc, argv);

    int arr[] = {1, 2, 3, 4, 5};

    forEach(arr, 5, printNumber);  // 使用printNumber作为回调函数

    device.userCallbackFunc(9);

    

    return 0;

}

三.效率对比

C++中 直接调用、函数指针、std::function效率对比

调用次数:10亿次

CPU:  i7 860  (主频2.8GHz)

测试结果: 函数指针要比直接调用慢2s左右;std::function 要比函数指针慢2s左右

该测试结果链接:https://cherishlc.iteye.com/blog/2002095

三.实现成员函数作为回调函数

使用std::bind和std::function的回调实现;

可参照文章:

https://blog.csdn.net/qq_34915586/article/details/103143339

04-10 17:34