首页 > 编程语言 >C++与Qt中回调函数的两种实现方法

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

时间:2024-04-09 09:29:05浏览次数:15  
标签:std function Qt int C++ 函数指针 回调 函数

一.回调函数介绍

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

标签:std,function,Qt,int,C++,函数指针,回调,函数
From: https://blog.csdn.net/xieliru/article/details/137536743

相关文章

  • 20240408,C++数组,函数,指针
    是谁说回老家学习结果摆烂了两天,是我,Π—Π! Π—Π!! 一,数组——同C1.1一维数组1.0  相同类型,连续内存,1.1  定义格式:数据类型数组名【长度】;数组类型数组名【长度】={1,2,3,……};数组类型数组名【】={1,2,3,……};1.2  遍历数组,初始化,下标【0-N】1.3  数组名:数......
  • 【C++对C语言的拓展】引用--3
    1.8指针引用#include <iostream>usingnamespace std; struct Teacher { char name[64]; int age ; }; //在被调⽤用函数获取资源int getTeacher(Teacher **p) {     Teacher *tmp = NULL; if (p == NULL)......
  • C++奇迹之旅:我与类和对象相遇
    文章目录......
  • C++ 入门一
    C++入门一1.C++关键字2.命名空间2.1命名空间定义2.2命名空间使用3.C++输入&输出C++是一种高级编程语言,由BjarneStroustrup在20世纪80年代初期在贝尔实验室开发。它是对C语言的扩展,添加了面向对象编程的特性,如类和对象、继承、多态和封装。C++支持多种编程范式,......
  • 【简单讲解下C++max函数的使用】
    ......
  • react 函数组件和hook
    函数组件1.函数组件没有生命周期2.函数组件没有this3.函数组件通过hook完成各种操作4.函数组件本身就是render函数5.props在函数第一个参数解释useState参考https://www.cnblogs.com/ssszjh/p/14581014.htmlprops参考https://www.cnblogs.com/ssszjh/p/18118746生命周期......
  • C++中lambda表达式介绍
    c++在c++11标准中引入了lambda表达式,一般用于定义匿名函数,使得代码更加灵活简洁。lambda表达式与普通函数类似,也有参数列表、返回值类型和函数体,只是它的定义方式更简洁,并且可以在函数内部定义。什么是Lambda表达式最常见的lambda的表达式写法如下autoplus=[](intv1,int......
  • 【Kotlin】运算符函数、解构函数、中缀函数
    1一元运算符函数1.1符号和函数符号函数+aa.unaryPlus()-aa.unaryMinus()!aa.not()a++a.dec()a--a.inc()1.2案例funmain(){varstu=Student("Tom",13)println(-stu)//打印:[moT,31]}classStudent(varname:String,va......
  • 【Kotlin】扩展属性、扩展函数
    1类的扩展​Kotlin提供了扩展类或接口的操作,而无需通过类继承或使用装饰器等设计模式,来为某个类添加一些额外的属性或函数,我们只需要通过一个被称为扩展的特殊声明来完成。通过这种机制,我们可以将那些第三方类不具备的功能强行进行扩展,方便我们的操作。1.1扩展内置类1.1......
  • 【C++11】C++11深度解剖
    >作者:დ旧言~>座右铭:松树千年终是朽,槿花一日自为荣。>目标:了解在C++11相关知识>毒鸡汤:苦尽甘来的那一天,山河星月都作贺礼。>专栏选自:C嘎嘎进阶>望小伙伴们点赞......