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

一.回调函数介绍

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++风格实现

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

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C++ Qt是一种流行的GUI开发框架,它结合了C++语言的强大性能和Qt库的丰富功能。在Qt回调函数是一种常见的编程模式,用于实现事件处理和信号与槽机制。 回调函数是指在特定事件发生时被调用的函数。在Qt回调函数通常用于处理用户界面的事件,例如按钮点击、菜单选择等。当这些事件发生时,Qt会自动调用相应的回调函数来执行特定的操作。 在C++ Qt回调函数可以通过以下几种方式实现: 1. 普通函数指针:可以将一个普通的C++函数指针作为回调函数传递给Qt的信号与槽机制。当信号触发时,Qt会调用该函数指针所指向的函数。 2. 函数对象:可以使用C++的函数对象(Functor)作为回调函数。函数对象是一个类对象,重载了函数调用运算符(),可以像函数一样被调用。在Qt,可以将函数对象作为回调函数传递给信号与槽机制。 3. Lambda表达式:C++11引入了Lambda表达式,它可以方便地定义匿名函数。在Qt,可以使用Lambda表达式作为回调函数,直接在信号与槽连接语句定义并传递Lambda表达式。 下面是一个简单的示例,演示了如何在C++ Qt使用回调函数: ```cpp #include <QApplication> #include <QPushButton> // 普通函数作为回调函数 void myFunction() { qDebug() << "Button clicked!"; } int main(int argc, char *argv[]) { QApplication app(argc, argv); QPushButton button("Click me!"); QObject::connect(&button, &QPushButton::clicked, myFunction); button.show(); return app.exec(); } ``` 在上面的示例,我们创建了一个QPushButton按钮,并将其clicked信号与myFunction函数进行连接。当按钮被点击时,myFunction函数会被调用,并输出一条消息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI+程序员在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值