仿函数 VS 函数指针回调

发布时间:2026/11/1 20:45:53

仿函数 VS 函数指针回调 目录摘要一函数指针回调解决问题①函数回调②函数回调模版二仿函数解决问题①仿函数②仿函数模版三仿函数的优势摘要本博客对比函数指针实现回调和仿函数去解决同一个问题突出仿函数的优势。一函数指针回调解决问题现在我们有一个类A其中有一个成员函数void func(int xx, int yy)我们有时候想要知道xx是否比yy谁大有时候想知道xx是否比yy小请问怎么做呢①函数回调我们让类A的成员变量新增一个函数指针类型_pf同理构造函数接收一个函数指针类型的变量pf赋给_pf当我们想比较xx和yy谁小的时候我们就传递lessfc的函数指针过去然后在类A的成员函数func中调用_pf(xx,yy)也就是使用这个lessfc函数比较谁小同理当我们想比较xx和yy谁大的时候我们就传递greaterfc的函数指针过去然后在类A的成员函数func中调用_pf(xx,yy)也就是使用这个greaterfc函数比较谁大//lessfc函数 xy bool lessfc(int x, int y) { return x y; } //greaterfc函数 xy? bool greaterfc(int x, int y) { return x y; } // A这个类体现了---函数指针实现回调 class A { public: A(bool(*pf)(int, int))//构造函数接收一个函数指针 并赋值给成员变量 :_pf(pf) {} void func(int xx, int yy)//func函数接收两个参数 { cout void func(int xx, int yy) _pf(xx, yy) endl;; } //用接收到的函数指针结合两个int参数调用该函数 bool(*_pf)(int, int);//成员变量也是一个函数指针类型 }; int main() { A aa1(lessfc);//创建一个对象 aa1.func(1, 2);//调用对象的func函数 且传两个int A aa2(greaterfc);//创建一个对象 aa2.func(1, 2);//调用对象的func函数 且传两个int }运行结果②函数回调模版当然上面的函数回调的例子比较局限于xx和yy为int类型我们一般会加上模版参数//lessfc函数 xy templateclass T bool lessfc(T x, T y) { return x y; } //greaterfc函数 xy? templateclass T bool greaterfc(T x, T y) { return x y; } // A这个类体现了---函数指针实现回调 templateclass T class A { public: A(bool(*pf)(T, T))//构造函数接收一个函数指针 并赋值给成员变量 :_pf(pf) {} void func(T xx, T yy)//func函数接收两个参数 { cout void func(T xx, T yy) _pf(xx, yy) endl;; } //用接收到的函数指针结合两个int参数调用该函数 bool(*_pf)(T, T);//成员变量也是一个函数指针类型 }; int main() { Aint aa1(lessfc);//因为有模版所以显式传模版的类型去创建一个对象 aa1.func(1, 2);//调用对象的func函数 且传两个int 与创建时T的类型吻合 Adoubleaa2(greaterfc);//因为有模版所以显式传模版的类型创建一个对象 aa2.func(1.1, 1.0);//调用对象的func函数 且传两个double 与创建时T的类型吻合 }解释加上模版之后范围更广了⚠️函数回调虽然达到了我们想要的效果但是缺点众多1就是类型书写麻烦2就是会影响了类的成员变量和构造函数二仿函数解决问题而仿函数就是更优秀的解决方法①仿函数我们实现一个两个类分别叫做lessfc和greaterfc两个类内部都对()运算符进行重载lessfc对()运算符重载为返回参数x是否比y小的bool值而greaterfc重载内部返回参数x是否比y大的bool值然后类A新增一个模版参数Comapre其接收lessfc或者lessfc两个仿函数中的一个当我们类A内部的func想比较xx是否比yy小的时候则我们传递给Comapre参数lessfc然后在类A内部创建Comapre com也就是创建了一个lessfc的对象然后在func内部调用com的成员函数()运算符重载com(xx, yy)即可同理func想比较xx是否比yy大不再赘述....//定义仿函数 class lessfc //将之前的lessfc函数封装成一个类 { public: //类中仅需对()这个操作符进行重载 bool operator()(const int x, const int y) { return x y; } }; //定义仿函数 class greaterfc //将greaterfc函数封装成一个类 { public: //类中仅需对()这个操作符进行重载 bool operator()(const int x, const int y) { return x y; } }; templateclass Comapre class A//A这个类要使用仿函数 { public: void func(int xx, int yy) { Comapre com;//创建一个 Comapre 类型的对象 com。 cout void func(int xx, int yy) com(xx, yy) endl;; //调用 com(xx, yy)即调用仿函数的 operator()比较 xx 和 yy。 } }; int main() { Alessint aa1; aa1.func(1, 2); // 输出 1 2 的结果true Agreaterint aa2; aa2.func(1, 2); // 输出 1 2 的结果false }运行结果解释优点在于我们不用复杂的书写函数指针类型其次我们不用修改成员变量和构造函数了我们只需给类A新增一个模版参数Comapre即可②仿函数模版当然同理我们加上模版参数T应用的范围更广泛了//定义仿函数 templateclass T class lessfc //将之前的lessfc函数封装成一个类 { public: //类中仅需对()这个操作符进行重载 bool operator()(const T x, const T y) { return x y; } }; //定义仿函数 templateclass T class greaterfc //将greaterfc函数封装成一个类 { public: //类中仅需对()这个操作符进行重载 bool operator()(const T x, const T y) { return x y; } }; templateclass Comapre, class T class A//A这个类要使用仿函数 { public: void func(T xx, T yy) { Comapre com;//创建一个 Comapre 类型的对象 com。 cout void func(T xx, T yy) com(xx, yy) endl;; //调用 com(xx, yy)即调用仿函数的 operator()比较 xx 和 yy。 } }; int main() { Alessint, int aa1; aa1.func(1, 2); // 输出 1 2 的结果true Agreaterdouble, double aa2; aa2.func(1.1, 1.0); // 输出 1.1 1.0 的结果ture }运行结果三仿函数的优势1. 更灵活的功能扩展仿函数仿函数是一个类对象可以包含成员变量和成员函数因此可以在调用时保存状态例如计数器、配置参数等。函数指针函数指针只能指向一个静态函数无法保存状态功能扩展性较差。2. 更高的性能仿函数仿函数通常是内联的inline编译器可以优化其调用减少函数调用的开销。函数指针函数指针的调用需要通过指针间接调用无法内联性能稍差。3. 更强的类型安全仿函数仿函数是类对象类型信息在编译时确定类型安全性更高。函数指针函数指针的类型信息较弱容易出错例如指向错误类型的函数。4. 更好的通用性仿函数仿函数可以与模板结合实现高度通用的代码。例如STL 中的排序算法 std::sort 可以通过传入不同的仿函数实现升序或降序排序。函数指针函数指针的通用性较差难以与模板结合。5. 支持运算符重载仿函数仿函数可以重载 operator()使得对象可以像函数一样被调用语法更直观。函数指针函数指针的调用语法较为繁琐。6. 更易于组合和扩展仿函数仿函数可以通过继承、组合等方式扩展功能。函数指针函数指针的功能扩展性较差难以实现复杂的逻辑组合。 [ 作者 ] shylyly [ 首次发布 ] 2025.3.2❌ [ 最新修改 ] 2026.9.2 [ 声明 ] 由于笔者水平有限文中难免有疏漏或不妥之处还望读者不吝赐教
延伸阅读

更多相关文章

2026/11/1 20:45:10

评估dso直接稀疏里程计

部署好dso直接稀疏里程计后,运行数据集生成result.txt,使用evo进行评估 出现问题 1.(1)问题:生成的result.txt第一列“时间戳”均为0 (2)解决: 在运行数据集下,新建一…

2026/10/30 4:29:29

量子计算、通信与测量三大核心技术突破与产业化应用分析

如果你最近关注科技新闻,可能会注意到一个现象:量子技术领域的突破性消息突然密集出现。从量子计算原型机的性能提升,到量子通信网络的实际部署,再到量子测量技术的产业化应用——这些进展不再是实验室里的遥远概念,而…

2026/10/31 0:07:53

Tyler-1:面向嵌入式入门的可拆解实体教具

简介:本资源是面向Arduino初学者与创客教育者的智能模型车实践项目——“太乐1号(Tyler-1)”完整源码包,融合电子控制、机械搭建与移动终端交互,解决入门者在软硬协同开发中缺乏系统性项目参考的痛点,适用于…

2026/11/1 2:01:37

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

2026/11/1 2:01:37

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

2026/11/1 2:01:37

关于“贾子猜想”的数学地位、结构特征与讨论边界

关于“贾子猜想”的数学地位、结构特征与讨论边界摘要 本文对“贾子猜想”进行基于公开表述与现有数学事实的分析。该猜想主张:当正整数 n3m>5(即 n6,9,12,15,…)时,方程x₁ⁿ x₂ⁿ ⋯ xₙⁿ yⁿ不存在正整数解。文章首先…

2026/11/1 2:01:37

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

2026/11/1 2:01:37

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

2026/11/1 1:56:37

华为OD机试真题 新系统 2026-10-28 JavaGoC【社交网络消息转发】

目录 题目 思路 Code 题目 题目内容: 在一个社交网络中,有 N 个用户(编号 0 到 N−1);每个用户都有一个「转发名单」(整数),该数二进制格式中的第 i 位为 1 表示此用户会把消息转发给第 i 个用户。 给定一个整数数组 forwardLists 和一个整数 initialSenders,请…

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑