【C++】回调函数和回调对象

文章目录

    • 回调
    • 可调用对象
    • 函数指针作回调
    • 函数对象作回调
      • 函数对象的使用
      • std::function【C++11】
      • 作回调使用
    • 【C++11】Lambda表达式作回调
    • 【C++11】bind对象作回调
      • std::bind的使用
      • 作回调使用

回调

  • 当发生某种事件时需要调用或触发另一个事件即为回调,回调的核心即为将可调用对象作为参数传递,在满足某种条件时执行。

可调用对象

  • 可调用对象包括函数、函数指针、函数对象/仿函数【C++】、Lambda表达式【C++11】、bind对象【C++11】

函数指针作回调

  • int (*Callback)(int,int);函数指针Callback指向一个返回值为int类型,传参为两个int类型的函数,例如int add(int x,int y);

// 定义回调函数类型(函数指针)
typedef int (*Callback)(int,int);// 回调事件(接受回调)
void Event(Callback cb,int x,int y) {std::cout<<cb(x,y)<<std::endl; // 触发回调
}// 实际回调
int My_Callback(int x,int y) {return x+y+100;
}int main() {int x{0};int y{0};cin>>x>>y;Event(My_Callback,x,y); // 注册回调return 0;
}

函数对象作回调

函数对象的使用

  • 函数对象即仿函数,实际上是类中对于()运算符进行重载operator(),本质是对象调用其成员函数(成员方法)。
class MyPrint {
public:
//重载()运算符void operator()(string text) {cout << text << endl;}
};
class MyAdd {
public:int operator()(int a, int b) {return a + b;}
};
int main() {MyPrint my;my("你好");//my.operator()("你好");//函数对象即仿函数实质是对函数运算符()的重载MyAdd add;cout<<add(5, 5)<<endl;return 0;
}

std::function【C++11】

  • C++11引入的通用可调用对象包装器它可以存储、复制和调用任何可调用对象,作用其实类似于函数指针,只不过函数指针只适用于函数,而std::function适用于所有的可调用对象。
  • std::function<返回值类型(参数类型1, 参数类型2, …)>
//示例-存储普通函数
#include <iostream>
#include <functional>int add(int a, int b) {return a + b;
}int main() {std::function<int(int, int)> func = add;  // 存储函数指针std::cout << func(2, 3);  // 输出 5return 0;
}

作回调使用

  • 函数对象作回调是整个对象被传递,而不仅仅是函数,可以携带自己的属性
#include<iostream>
#include<functional>
using namespace std;typedef std::function<int(int,int)> callback;// 实际回调
class My_Callback{public:int operator()(int x,int y){return x+y+other;}int other{100};//函数对象可以保存自己的属性
};// 回调事件(接受回调)
void Event(callback cb,int x,int y) {std::cout<<cb(x,y)<<std::endl; // 触发回调
}int main() {int x{0};int y{0};cin>>x>>y;My_Callback Callback;Event(Callback,x,y); // 注册回调return 0;
}

【C++11】Lambda表达式作回调

  • Lambda表达式实际上可以看作一段可调用的函数代码,具体使用方法可见文章C++11 Lambda表达式以及 C++11新特性 第9点,在此不再赘述。
//Lambda表达式作回调
#include<iostream>
#include<functional>
using namespace std;typedef std::function<int(int,int)> callback;// 回调事件(接受回调)
void Event(callback cb,int x,int y) {std::cout<<cb(x,y)<<std::endl; // 触发回调
}int main() {int x{0};int y{0};cin>>x>>y;// 实际回调函数(Lambda)auto Callback = [](int x,int y){return x+y+100;};Event(Callback,x,y); // 注册回调return 0;
}

【C++11】bind对象作回调

std::bind的使用

  • std::bind用于将函数和参数绑定成一个可调用对象,可以和std::function配合使用,绑定后的结果可以使用std::function存储
//std::bind的使用#include<iostream>
#include<functional>
using namespace std;int My_Callback(int x,int y) {return x+y+100;
}int main() {int x{0};int y{0};cin>>x>>y;auto Callback= std::bind(&My_Callback,x,y);std::cout<<Callback()<<std::endl;return 0;
}

作回调使用

#include<iostream>
#include <functional>
using namespace std;class My_Callback{public:int add(int x,int y){return x+y+other;}int other{100};//函数对象可以保存自己的属性
};int main() {int x{0};int y{0};cin>>x>>y;My_Callback Callback;//需要调用成员方法add,所以必须传this(即Callback)std::function<int(int,int)> callback = std::bind(&My_Callback::add,&Callback,std::placeholders::_1, std::placeholders::_2); //std::placeholders::_1, std::placeholders::_2即为占位符,表示有两个参数//等价于 std::function<int(int,int)> callback=[&Callback](int x,int y){return Callback.add(x,y);};std::cout<<callback(x,y)<<std::endl; /*也可直接绑定参数即:std::function<int()> callback = std::bind(&My_Callback::add,&Callback,x,y);//等价于 std::function<int()> callback=[&Callback,x,y](){return Callback.add(x,y);};std::cout<<callback()<<std::endl; */return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/73442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DeepSeek助力文案,智能音箱如何改变你的生活?

你好&#xff0c;我是三桥君 你有没有为写智能音箱的宣传文案而抓耳挠腮过&#xff1f;三桥君在这方面可是有些感想&#xff0c;今天就来给你唠唠怎么用DeepSeek写出超赞的智能音箱宣传文案。 首先&#xff0c;你得给DeepSeek喂足“料”。这就好比做饭&#xff0c;你得准备好各…

【区块链安全 | 第一篇】密码学原理

文章目录 1.哈希函数1.1 哈希函数的性质1.2 常见哈希算法1.3 Merkle Tree&#xff08;默克尔树&#xff09;1.4 HMAC&#xff08;哈希消息认证码&#xff09; 2. 公钥密码学2.1 对称加密 vs 非对称加密2.2 RSA 算法2.3 ECC&#xff08;椭圆曲线密码学&#xff09;2.4 Diffie-He…

基于websocketpp实现的五子棋项目

该博客对于学完C和linux操作系统&#xff0c;但不知道如何用C开发项目&#xff0c;已经不知道C如何使用第三方库的人来说一定很有帮助&#xff0c;请耐心看完&#xff01; 先看一下游戏会显示的前端界面&#xff0c;对理解这个游戏的前后端交互过程会有帮助 1. 开发环境 1.1 …

基于Redis分布锁+事务补偿解决数据不一致性问题

基于Redis的分布式设备库存服务设计与实现 概述 本文介绍一个基于Redis实现的分布式设备库存服务方案&#xff0c;通过分布式锁、重试机制和事务补偿等关键技术&#xff0c;保证在并发场景下库存操作的原子性和一致性。该方案适用于物联网设备管理、分布式资源调度等场景。 …

RK3568笔记八十: Linux 小智AI环境搭建

若该文为原创文章&#xff0c;转载请注明原文出处。 最近小智AI火了&#xff0c;韦老师出了 Linux 小智 AI 聊天机器人 版本&#xff0c;想移植到 RK3568上&#xff0c; 由于和韦老师硬件不同&#xff0c;所以需要交叉编译一些库&#xff0c;为后续移植做准备。 一、环境 1、…

C# SerialPort 使用详解

总目录 前言 在工业控制、物联网、嵌入式开发等领域&#xff0c;串口通信&#xff08;Serial Port Communication&#xff09;是连接串行设备&#xff08;如条码扫描器、GPS接收器等&#xff09;与计算机的重要手段。C# 提供了内置的 SerialPort 类&#xff0c;简化了串口开发…

3D点云的深度学习网络分类(按照作用分类)

1. 3D目标检测&#xff08;Object Detection&#xff09; 用于在点云中识别和定位目标&#xff0c;输出3D边界框&#xff08;Bounding Box&#xff09;。 &#x1f539; 方法类别&#xff1a; 单阶段&#xff08;Single-stage&#xff09;&#xff1a;直接预测3D目标位置&am…

LabVIEW 与 PLC 通讯的常见方式

在工业自动化和数据采集系统中&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09; 广泛用于控制和监测各种设备&#xff0c;而 LabVIEW 作为强大的图形化编程工具&#xff0c;常用于上位机数据处理和可视化。为了实现 LabVIEW 与 PLC 的高效通讯&#xff0c;常见的方法包…

2025 polarctf春季个人挑战赛web方向wp

来个弹窗 先用最基础的xss弹窗试一下 <script>alert("xss")</script>没有内容&#xff0c;猜测过滤了script&#xff0c;双写绕过一下 <scrscriptipt>alert("xss")</scscriptript>background 查看网页源代码 查看一下js文件 类…

【Ai】--- 可视化 DeepSeek-r1 接入 Open WebUI(超详细)

在编程的艺术世界里,代码和灵感需要寻找到最佳的交融点,才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里,我们将共同追寻这种完美结合,为未来的世界留下属于我们的独特印记。【Ai】--- 可视化 DeepSeek-r1 接入 Open WebUI(超详细) 开发环境一、前情提要:你…

7.1-7.2考研408数据结构查找算法核心知识点深度解析

考研408数据结构查找算法核心知识点深度解析 一、查找基本概念 1.1 核心定义与易错点 查找表与关键字 易错点:混淆静态查找表(仅查询)与动态查找表(含插入/删除操作)的应用场景。例如哈希表属于动态查找结构,而分块查找适用于静态数据。难点:理解平均查找长度(ASL)的…

Redis--redis客户端

目录 一、引言 二、数据库管理命令 三、redis客户端 四、Java客户端使用Redis 五、相关命令使用 1.get&#xff0c;set 2.exists&#xff0c;del 3.keys 4.expire&#xff0c;ttl 六、总结 一、引言 在之前学了redis相关类型命令之后&#xff0c;本篇文章&#xff0c;…

SpringBoot3.0不建议使用spring.factories,使用AutoConfiguration.imports新的自动配置方案

文章目录 一、写在前面二、使用imports文件1、使用2、示例比对3、完整示例 参考资料 一、写在前面 spring.factories是一个位于META-INF/目录下的配置文件&#xff0c;它基于Java的SPI(Service Provider Interface)机制的变种实现。 这个文件的主要功能是允许开发者声明接口的…

鸿蒙特效教程10-卡片展开/收起效果

鸿蒙特效教程10-卡片展开/收起效果 在移动应用开发中&#xff0c;卡片是一种常见且实用的UI元素&#xff0c;能够将信息以紧凑且易于理解的方式呈现给用户。 本教程将详细讲解如何在HarmonyOS中实现卡片的展开/收起效果&#xff0c;通过这个实例&#xff0c;你将掌握ArkUI中状…

hn航空app hnairSign unidbg 整合Springboot

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 逆向分析 学习unidbg补环境。先弄一个…

奇怪的异形选项卡样式、弧形边框选项卡

<template><div :class"$options.name"><div class"tab">默认选项卡</div><div class"tab" active>选中选项卡</div><el-divider /><el-tabs v-model"tabActiveName" tab-click"(t…

特殊行车记录仪DAT视频丢失的恢复方法

行车记录仪是一种常见的车载记录仪&#xff0c;和常见的“小巧玲珑”的行车记录仪不同&#xff0c;一些特种车辆使用的记录仪的外观可以用“笨重”来形容。下边我们来看看特种车载行车记录仪删除文件后的恢复方法。 故障存储: 120GB存储设备/文件系统:exFAT /簇大小:128KB 故…

UE5小石子阴影在非常近距离才显示的问题

Unreal中采用LandscapeGrass生成的地形&#xff0c;在MovieRenderQueue中渲染时阴影显示距离有问题&#xff0c;在很近的时候才会有影子&#xff0c;怎么解决&#xff1f; 地面上通过grass生成的小石子的阴影只能在很近的时候才能显示出来&#xff0c;需要如下调整 r.Shadow.R…

零基础上手Python数据分析 (9):DataFrame 数据读取与写入 - 让数据自由穿梭

回顾一下,上篇博客我们学习了 Pandas 的核心数据结构 Series 和 DataFrame。 DataFrame 作为 Pandas 的 “王牌” 数据结构,是进行数据分析的基石。 但 DataFrame 的强大功能,还需要建立在 数据输入 (Input) 和 数据输出 (Output) 的基础上。 数据从哪里来? 分析结果又如何…

【商城实战(65)】退换货流程全解析:从前端到后端的技术实现

【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配,乃至运营推广策略,102 章内容层层递进。无论是想…