C++的回调函数

一、简介

本文主要介绍C++中如何使用回调函数。

二、回调函数介绍

回调函数主要在”回”字,和正常的函数调用方式不太一样。正常的函数由开发者自己定义返回类型以及传入的参数,并且也是由开发者自己调用,而回调函数功能其实也是由开发者自己实现,但是返回类型以及入参则由注册回调的函数来决定(若是自己编写则可以自定义注册函数,由他人提供则只能根据接口实现),而且调用方也不是开发者,而是注册方决定。

整个过程也就是一个”回”字,开发者将自己的函数指针交给对方,这是”去”,而对方则在适当的时候调用这个函数,也可以将一些开发者需要的数据传回来,这便是来回了。

总而言之,正常情况是开发者调用API,调用权在开发者手中,而回调函数则相当于API调用开发者提供的函数,主被动转换了。

三、回调函数用处

那么,回调函数的用处是什么呢?既然发明了回调函数,自然是有其用武之地了。

如果你对上面的解释比较理解的话,你就会发现回调函数真的用的很多,比如事件,其底层就是回调函数,比如最简单的UI窗口鼠标点击事件,是否是由开发者编写函数具体实现,而调用的时机是由UI框架决定呢?不过很多开发者可能由于框架封装的十分简单易用,所以没有察觉到。

四、回调函数示例

了解了概念后,我们自然是要学习如何自己实现回调函数的注册了。本文以C++为例。

void sample(void (*callback)())

{

callback();

}

void callbackFun1()

{

std::cout << “call the function1” << std::endl;

}

void callbackFun2()

{

std::cout << “call the function2” << std::endl;

}

int main()

{

sample(callbackFun1);

sample(callbackFun2);

std::system(“pause”);

return 0;

}

C++的回调函数

如上所示,这便是最简单的回调函数了。

sample函数的入参为void (callback) (),共有三部分,void 表示返回类型,(callback)为函数指针,() 则代表回调函数的入参,此处无入参。

因此只要是返回类型为void,参数为空的函数,sample都能够调用。

一般为了方便调用,都会使用typedef,如下。

typedef int (*myFun) (int&, int);

int sample(myFun mF, int& a, int b)
{
    b = 2;
    return mF(a, b);
}

int callbackFun1(int& a, int b)
{
    a++;
    return a+b;
}

int main()
{
    int a = 0;
    int b = 1;
    int c = sample(callbackFun1, a, b);

    std::cout << "a = " << a << "  b = " << b << "  c = " << c << std::endl;

    std::system("pause");

    return 0;
}

C++的回调函数

结果是否和你计算的一样呢?

以上都是直接触发,但是大部分框架可就复杂多了,可不是这么简单的调用,只会在需要的时候才会触发!

typedef int (*myFun) (int&, int);

struct fun
{
    myFun mF;
    int a;
    int b;

    fun(myFun _mF, int _a, int _b)
    {
        mF = _mF;
        a = _a;
        b = _b;
    }
};

std::vector funs;

void regisiterCallback(myFun mF, int& a, int b)
{
    funs.emplace_back(fun(mF, a, b));
}

int callbackFun1(int& a, int b)
{
    return a+b;
}

int main()
{
    int a = 0;
    int b = 0;
    regisiterCallback(callbackFun1, a, b);

    a++;
    b++;
    regisiterCallback(callbackFun1, a, b);

    std::cout << funs[1].mF(funs[1].a, funs[1].b) << std::endl;
    std::cout << funs[0].mF(funs[0].a, funs[0].b) << std::endl;

    std::system("pause");

    return 0;
}

C++的回调函数

如上regisiter函数只是负责注册回调,并没有触发回调函数,在main中才真正调用,并且我特意先调用了第二个注册的回调,结果也是先输出了第二个注册的回调,因此回调函数的调用先后顺序与注册顺序没有关系,只跟注册方实际调用顺序有关。

五、总结

本文内容为我个人之谈,如有错误,欢迎指正!

Original: https://www.cnblogs.com/Clark-Zhang/p/16687560.html
Author: 朔月の流光
Title: C++的回调函数

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/582744/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • C语言传指针类型的形参

    今天在牛客网上做C语言专项练习题,遇到一个”函数传指针类型的形参”的题,我做错了,正确的为下面代码: #include <string.h> #…

    Linux 2023年6月13日
    073
  • wsl2环境搭建

    我电脑配置不高,开虚拟机跑linux总觉得太卡。最近才了解到windows早就上了wsl2——一款较为轻量的虚拟机软件。所以本篇博客偏笔记向,存粹记录以便多次使用。 WSL2安装 …

    Linux 2023年6月7日
    082
  • CentOS导入CA证书

    把CA证书放到如下目录 /etc/pki/ca-trust/source/anchors 再命令行运行 /bin/update-ca-trust 如下所示的操作步骤 删除证书只需要…

    Linux 2023年6月6日
    091
  • uniapp使用阿里云矢量图标库,h5端显示正常,真机app不显示问题解决

    1、在阿里云矢量图标库网站管理界面如上图,首先下载至本地1的位置,然后在2的位置复制代码 2、在下图中static目录下放入下载的iconfont.css文件,并且修改里面的链接,…

    Linux 2023年6月7日
    092
  • linux用户组管理

    一、简介 1、每个用户都有一个用户组,系统可以对一个用户组中的所有用户进行集中管理,不同Linux系统对用户组的规定有所不同,如:Linux下在创建用户时,不指定用户组名,则会同时…

    Linux 2023年5月27日
    0118
  • SUPERVISOR监控tomcat配置文件

    下方为Supervisor管理tomcat的配置,多注意红色位置路径修改: [program:tomcat] ; 管理的子程序名字,要和项目有关联,不能乱写 command=/us…

    Linux 2023年6月6日
    087
  • LeetCode 899.有序队列|字符串最小表示法的使用|求循环字符串的最小值

    Tags: #String For a string s, each time you can choose one of first k letters and put it t…

    Linux 2023年6月13日
    090
  • 15、16、17思维导图

    posted @2022-04-24 10:20 20191223张俊怡 阅读(31 ) 评论() 编辑 Original: https://www.cnblogs.com/zzj…

    Linux 2023年6月8日
    0135
  • redis压力测试【转】

    本文转自: https://segmentfault.com/a/1190000015571891 redis自带的redis-benchmark工具 Redis 自带了一个叫re…

    Linux 2023年5月28日
    068
  • WebBug Java漏洞靶场 Java代码审计

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Linux 2023年6月6日
    099
  • SpringBoot入门-Redis(六)

    package com.vast; import com.vast.dao.AccountRepository; import com.vast.dao.IAccountMybat…

    Linux 2023年5月28日
    064
  • CentOS-7配置fastDFS文件服务器和安装Nginx

    配置步骤实在是很繁琐,听我慢慢道来! 主要是配置管理(tracker)和存储(storage)返回地址样式 –> 域名/组名/磁盘名/目录名/文件名 &#8211…

    Linux 2023年6月13日
    090
  • CentOS 6 安装并配置 MySQL 5.6

    1. 添加 MySQL Yum 存储库 将MySQL Yum存储库添加到系统的存储库列表中; 1.1 到MySQL官网下载MySQL Yum存储库(https://dev.mysq…

    Linux 2023年5月27日
    0116
  • linux添加磁盘及分区挂载

    磁盘管理 1.为什么要添加磁盘 2.系统添加磁盘并分区 磁盘管理 1.为什么要添加磁盘 随着系统的使用,磁盘的内容会越来越少,所以有必要添加磁盘来增加空间。 [En] With t…

    Linux 2023年5月27日
    088
  • Python环境安装

    一、下载地址: Python:Download Python | Python.org PyCharm:Download PyCharm: Python IDE for Profe…

    Linux 2023年6月13日
    0103
  • 渣画质视频秒变清晰,“达芬奇”工具集帮你自动搞定

    https://www.msra.cn/zh-cn/news/features/davinci 2022-06-23 | 作者:微软亚洲研究院 编者按:是否时常”考古&…

    Linux 2023年6月13日
    0176
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球