当前位置: 首页 > news >正文

【C++】仿函数和回调函数

1 仿函数

在 C++ 中,仿函数(Functor)是一种特殊的对象,它可以像函数一样被调用。这种特性通过重载对象的 operator() 运算符实现,使得对象在使用时可以拥有类似函数的行为。

仿函数的基本特点

  1. 本质是对象:仿函数是一个类的实例,不是普通函数
  2. 可调用性:通过重载 operator() 实现函数调用语法
  3. 状态保持:可以拥有成员变量,保存状态信息
  4. 类型特性:作为模板参数时能提供额外的类型信息
/*************************************************************************> File Name: test.cpp> Author: Winter> Created Time: Thu 21 Aug 2025 08:42:31 AM EDT************************************************************************/#include <iostream>
#include <vector>
#include <string>
#include <functional>
#include <algorithm>// 仿函数
struct SortByLength {bool operator() (const std::string& str1, const std::string& str2){return str1.size() < str2.size();}
};struct SortByLengthDesc {bool descending;              // 可调整的状态// 构造函数SortByLengthDesc(bool desc) : descending(desc) {}// 根据状态排序bool operator() (const std::string& str1, const std::string& str2){if (descending){return str1.size() > str2.size();}else{return str1.size() < str2.size();}}
};int main()
{/*************************仿函数案例*************************/std::cout << "=================仿函数案例:自定义排序=================" << std::endl;std::vector<std::string> words = {"a", "ab", "abc", "abcd", "b"};std::sort(words.begin(), words.end(), SortByLength());for (const auto& word : words){std::cout << word << std::endl;}std::cout << "==================================" << std::endl;std::sort(words.begin(), words.end(), SortByLengthDesc(true));for (const auto& word : words){std::cout << word << std::endl;}return 0;
}

测试

和lambda表达式差不多

2 回调函数

在 C++ 中,回调函数(Callback Function)是一种特殊的函数,它可以作为参数传递给另一个函数,并在特定事件发生或条件满足时被调用。这种机制允许程序在运行时动态决定需要执行的代码,增强了程序的灵活性和扩展性。

回调函数的基本原理

  1. 函数作为参数传递:将函数的地址(函数指针)作为参数传递给另一个函数
  2. 延迟执行:回调函数不会立即执行,而是在被调用函数内部的合适时机执行
  3. 事件驱动:常用于响应特定事件(如用户操作、完成某个任务等)

c风格的回调函数

#include <iostream>// 回调函数的原型
typedef void (*CallbackFunc)(int);// 接受回调函数作为参数的函数
void process(int data, CallbackFunc callback)
{std::cout << "处理数据: " << data << std::endl;// 在合适的时机调用回调函数callback(data);
}// 具体的回调函数实现
void printResult(int result)
{std::cout << "回调函数: 处理结果为 " << result << std::endl;
}int main()
{// 将函数名作为参数传递(函数名即函数地址)process(100, printResult);return 0;
}

测试

C++风格的回调,使用function

/*************************************************************************> File Name: test.cpp> Author: Winter> Created Time: Thu 21 Aug 2025 08:42:31 AM EDT************************************************************************/#include <iostream>
#include <functional>
#include <string>// 定义回调函数类型
using EventCallBack = std::function<void(const std::string& eventType, const std::string& messge)>;// 时间管理器:负责触发事件并调用回调
class EventManager {
private:EventCallBack callback;            // 存储回调函数public:// 注册回调函数void setCallBack(EventCallBack cb){callback = cb;}// 模拟触发事件void triggerEvent(const std::string& eventType, const std::string& messge){// 检查回调是否有效if (callback){callback(eventType, messge);                 // 调用回调函数}}
};void functionTest(const std::string& eventType, const std::string& messge)
{std::cout << eventType << " + " << messge << std::endl;
}int main()
{std::cout << "=== 回调函数案例:事件通知 ===" << std::endl;EventManager eventManager;// 注册回调eventManager.setCallBack(functionTest);// 触发回调eventManager.triggerEvent("hello", "world");// 使用lambda表达式eventManager.setCallBack([](const std::string& eventType, const std::string& messge) {std::cout << eventType << " ------ " << messge << std::endl;});eventManager.triggerEvent("hello", "world");return 0;
}

注意对比结果

3 回调函数和仿函数结合的案例

/*************************************************************************> File Name: test.cpp> Author: Winter> Created Time: Thu 21 Aug 2025 08:42:31 AM EDT************************************************************************/#include <iostream>
#include <functional>
#include <string>
#include <vector>// 仿函数:过滤数字
struct NumberFilter
{int threshold;           // 过滤值NumberFilter(int thresh) : threshold(thresh) {}// 重载()bool operator() (int num) const {return num > threshold;}
};using Callback = std::function<void(int)>;// 回调函数:处理过滤后的结果
void processNumbers(const std::vector<int>& nums, const NumberFilter& numberFilter, Callback callBack)
{for (int num :nums){if (numberFilter(num)){callBack(num);}}
}void functionTest(int a)
{std::cout << "----" << a << "----"<< std::endl;
} int main()
{std::cout << "\n=== 结合案例:带状态的过滤与回调 ===" << std::endl;std::vector<int> nums = {12, 5, 23, 8, 34, 1};// 创建带状态的仿函数(阈值为10)NumberFilter filter1(10);processNumbers(nums, filter1, functionTest);// 使用lambda表达式NumberFilter filter2(15);processNumbers(nums, filter2, [] (int num) {std::cout << "****" << num << "****"<< std::endl;});return 0;
}

测试

http://www.dtcms.com/a/342524.html

相关文章:

  • Python数值取整完全指南:从基础到金融工程实践
  • uniapp实现分页,效果如图
  • 自然语言处理——04 注意力机制
  • npm全局安装后,cmd命令行可以访问,vscode访问报错
  • HTTP 403 错误:后端权限校验机制深度解析
  • 长尾关键词优化SEO核心策略
  • JeeSite 快速开发平台:全能企业级快速开发解决方案
  • 自己动手,在Mac开发机上利用ollama部署一款轻量级的大模型Phi-3:mini
  • ElasticSearch——常用命令
  • VSCode Import Cost:5 分钟学会依赖瘦身
  • java16学习笔记
  • uniapp 全局弹窗
  • 力扣1005:k次取反后最大化的数组和
  • pycharm编译器如何快速掌握一个新模块的使用方法
  • K-means 聚类算法学习
  • matplotlib 6 - Gallery Images
  • 在 Linux 中全局搜索 Word 文档内容的完整指南
  • 从零搭建Kubernetes集群:常见踩坑与解决方案
  • Django中的MVC和MVT模式
  • Unity接入DeepSeek实现AI对话功能
  • 解析火语言 RPA 核心功能:让流程自动化更高效​
  • leetcode 76 最小覆盖子串
  • 有关spring-ai的defaultSystem与systemMessage优先级
  • AI 发展的伦理困局:在创新与规范间寻找平衡
  • MYSQL库及表的操作
  • Linux进程间传递文件描述符:为什么不能用FIFO而要用Unix域套接字?
  • 效果驱动复购!健永科技RFID牛场智能称重项目落地
  • 计算两幅图像在特定交点位置的置信度评分。置信度评分反映了该位置特征匹配的可靠性,通常用于图像处理任务(如特征匹配、立体视觉等)
  • 从数据抽取到加载:如何保障ETL中间环节的高效与稳定
  • 缓存与Redis