函数指针与函数对象

news/2025/12/3 22:26:49/文章来源:https://www.cnblogs.com/CodeAc/p/19304209

函数指针与函数对象

一、函数指针是什么?

函数指针的定义:在 C++ 中就是指向函数的指针变量,类型为 返回值类型(*)(参数类型列表),它保存的是函数的地址。通过函数指针,你可以动态调用指针指向的函数,实现更灵活的代码,比如回调函数、事件处理等。

简单来说,函数指针的作用是让你可以把函数当作变量来传递和调用。

举个简单例子:

// 定义一个普通函数
int add(int a, int b) {return a + b;
}int main() {// 定义一个函数指针,指向返回 int,参数是两个 int 的函数int (*funcPtr)(int, int) = add;// 通过函数指针调用函数int result = funcPtr(3, 4);std::cout << "Result: " << result << std::endl; // 输出 Result: 7return 0;
}

解释一下:

  • int (*funcPtr)(int, int):这是声明一个函数指针,指向返回 int 并且接收两个 int 参数的函数。
  • funcPtr = add;:把函数 add 的地址赋给函数指针。
  • funcPtr(3, 4);:通过函数指针调用函数。

二、函数对象是什么?

函数对象的定义:函数对象(也称为仿函数)是 C++ 中一种特殊的类,通过重载 operator()运算符,使得其实例可以像函数一样被调用(使用 对象名(参数)的语法)。

函数对象的特点:

  1. 可以携带状态​​:函数对象是类的实例,因此可以拥有成员变量,保存上下文信息(这是普通函数和 Lambda 无法直接具备的优势,尽管 Lambda 可以通过捕获列表模拟状态)。
  2. 行为可定制​​:通过不同的构造函数或成员变量,函数对象可以实现不同的行为。
  3. ​​类型安全​​:函数对象是具体的类型(由其类定义决定),而函数指针的类型由返回值和参数决定。

示例:自定义函数对象
假设我们需要一个回调函数,除了打印结果外,还能记录处理次数。可以用函数对象实现:

#include <iostream>// 函数对象:记录处理次数的回调
class CountingCallback {
public:CountingCallback() : count(0) {}// 重载 operator(),使实例可像函数一样调用void operator()(int value) {count++;  // 更新状态(处理次数)std::cout << "[计数] 第 " << count << " 次处理,结果: " << value << " ";}private:int count;  // 状态:已处理次数
};int main() {CountingCallback counter;  // 创建函数对象实例std::function<void(int)> callback = counter;  // 存储到 std::function// 模拟多次调用回调callback(10);  // 输出:[计数] 第 1 次处理,结果: 10callback(20);  // 输出:[计数] 第 2 次处理,结果: 20callback(30);  // 输出:[计数] 第 3 次处理,结果: 30return 0;
}

关键输出:

[计数] 第 1 次处理,结果: 10
[计数] 第 2 次处理,结果: 20
[计数] 第 3 次处理,结果: 30

问题:函数对象是什么?

结论:函数对象(Functor)是重载了 operator() 的类的实例,可像函数一样调用

函数对象(也称为仿函数)是 C++ 中一种特殊的类,通过重载 operator() 运算符,使得其实例可以像函数一样被调用(使用 对象名(参数) 的语法)。

函数对象的特点:
  1. 可以携带状态:函数对象是类的实例,因此可以拥有成员变量,保存上下文信息(这是普通函数和 Lambda 无法直接具备的优势,尽管 Lambda 可以通过捕获列表模拟状态)。
  2. 行为可定制:通过不同的构造函数或成员变量,函数对象可以实现不同的行为。
  3. 类型安全:函数对象是具体的类型(由其类定义决定),而函数指针的类型由返回值和参数决定。
示例:自定义函数对象

假设我们需要一个回调函数,除了打印结果外,还能记录处理次数。可以用函数对象实现:

#include <iostream>// 函数对象:记录处理次数的回调
class CountingCallback {
public:CountingCallback() : count(0) {}// 重载 operator(),使实例可像函数一样调用void operator()(int value) {count++;  // 更新状态(处理次数)std::cout << "[计数] 第 " << count << " 次处理,结果: " << value << " ";}private:int count;  // 状态:已处理次数
};int main() {CountingCallback counter;  // 创建函数对象实例std::function<void(int)> callback = counter;  // 存储到 std::function// 模拟多次调用回调callback(10);  // 输出:[计数] 第 1 次处理,结果: 10callback(20);  // 输出:[计数] 第 2 次处理,结果: 20callback(30);  // 输出:[计数] 第 3 次处理,结果: 30return 0;
}
关键输出:
[计数] 第 1 次处理,结果: 10
[计数] 第 2 次处理,结果: 20
[计数] 第 3 次处理,结果: 30

可以看到,函数对象 counter 内部维护了 count 状态,每次调用都会更新并打印处理次数。这种能力是普通函数(无状态)或 Lambda(依赖捕获的外部变量)难以直接实现的(Lambda 需要通过外部变量共享状态,而函数对象的状态是封装在自身对象中的)。

对比:函数指针 vs 函数对象 vs Lambda

类型 核心特点 是否可携带状态 典型用途
函数指针 指向普通函数的指针,无状态 简单回调(如日志、通知)
函数对象 重载 operator() 的类实例,可封装状态 是(通过成员变量) 需要上下文的回调(如计数、统计)
Lambda 表达式 匿名函数对象(本质是编译器生成的无名类实例),可捕获外部变量 是(通过捕获列表) 临时、简短的回调逻辑

总结

  • 函数对象是重载了 operator() 的类实例,可携带状态,适合需要上下文的回调场景。
  • std::function 作为通用回调容器,能统一包装函数指针、函数对象、Lambda 等可调用对象,提供灵活的回调机制。

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

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

相关文章

敏捷冲刺日志 - Day 5

敏捷冲刺日志 - Day 5 站立会议 站立时会议改为线上进行。昨天已完成的工作:saveVideoToGallery 功能已实现并测试通过。 初步定位了“替换”闪退问题的原因是 SecurityException。今天计划完成的工作:核心任务:尝试修…

12月3日日记

1.今天学习java web以及数据结合的复习 2.明天体育课打比赛 3.如何配置 StringRedisTemplate 和 RedisTemplate 的序列化(避免乱码 + 支持对象存储)?

第五篇Scrum冲刺博客

每日Scrum报告 日期: 2025-11-30 会议时间: 09:00 1. 当日站立式会议记录 会议照片成员同步内容 成员:齐思贤昨天已完成的工作:开发个人资料查询接口(GET /api/v1/users/me),返回用户详情(含review_count/coll…

敏捷冲刺日志 - Day 6

敏捷冲刺日志 - Day 6 站立会议 站立时会议改为线上进行。昨天已完成的工作:编写了兼容 Android 10 和 Android 11+ 的文件删除逻辑。 测试发现 Android 10 的 RecoverableSecurityException 方案不稳定。今天计划完成…

深入解析:Spring Kafka消费者被踢出组?CommitFailedException异常全面解析与解决方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

OWASP Java HTML 清理库曝出 XSS 漏洞:noscript 与 style 标签组合成隐患

OWASP Java HTML Sanitizer 库在某些特定策略配置下(允许 noscript 和 style 标签并允许 style 标签内含文本),存在跨站脚本漏洞。攻击者可构造特殊载荷绕过清理,导致 XSS 攻击。CVE-2025-66021:OWASP Java HTML …

敏捷冲刺日志 - Day 4

敏捷冲刺日志 - Day 4 站立会议 站立时会议改为线上进行。昨天已完成的工作:实现了视频的多选和队列压缩功能。 UI 可以正确显示批量压缩的进度。今天计划完成的工作:新功能:实现“保存到相册”功能,确保用户压缩的视…

计算机视觉黄金时代的回顾与展望

文章记录了资深科学家梅迪奥尼分享其40多年计算机视觉研究历程,重点阐述了从理解客户问题出发、逆向发明技术的方法论,并介绍了其在无感支付等场景下的实际应用,认为当前是计算机视觉解决现实商业问题的黄金时代。1…

homebrew运行机制

🍺 Homebrew 的结构 = 一个“酿酒厂” 以下是核心概念的真实意义 + 隐喻意义:1. Formula(配方) 真实意义: Homebrew 安装“源码软件”的脚本,描述软件从哪里下载、如何编译、有哪些依赖等。 隐喻: 👉 配方:…

解码构造与析构

构造与析构基础概念 核心定义构造函数:对象被创建时自动调用的特殊成员函数,唯一作用是初始化对象的成员属性,确保对象创建后处于合法可用状态。 析构函数:对象被销毁前自动调用的特殊成员函数,用于释放对象占用的…

敏捷冲刺日志 - Day 2

敏捷冲刺日志 - Day 2 站立会议 站立时会议改为线上进行。昨天已完成的工作:熟悉了项目初始版本(v1.0)的代码结构和功能。 分析了用户提出的三个核心需求:修复权限异常、界面汉化、增加批量处理。今天计划完成的工作…

10.结构型 - 代理模式 (Proxy Pattern)

代理模式 (Proxy Pattern) 在软件开发中,由于一些原因,客户端不想或不能直接访问一个对象,此时可以通过一个称为"代理"的第三者来实现间接访问.该方案对应的设计模式被称为代理模式. 代理模式(Proxy Design …

敏捷冲刺日志 - Day 1

敏捷冲刺日志 - Day 1 各个成员在 Alpha 阶段认领的任务 本次七天冲刺即为项目的 Alpha 阶段,目标是交付一个具备核心功能、可运行、可演示的最小可行产品(MVP)。团队成员在本阶段的任务分配如下:刘瑞康 (开发):负…

2025年中国集成灶十大品牌综合实力榜:选购指南与权威解析

body { font-family: "Microsoft YaHei", sans-serif; line-height: 1.8; color: rgba(51, 51, 51, 1); max-width: 1000px; margin: 0 auto; padding: 20px; background-color: rgba(249, 249, 249, 1) } h…

朝花夕拾OI回忆录

朝花夕拾 OI 回忆录 序言 或许是因为喜欢追忆吧,也或许是临近AFO,内心有一些触动,又或者是为了给后续的OIer一些前者的失败经验吧……总之,2025年12月3日,我十六岁生日这天,我决定写这篇 OI 回忆录,以记录我对O…

细胞因子:细胞信使的分子世界与功能解析

在复杂的多细胞生物体内,细胞间的信息交流是维持生命活动的基础。其中,细胞因子 作为一类关键的信使分子,在免疫调节、细胞生长、分化、炎症反应和组织修复等过程中扮演着不可或缺的角色。本文将深入探讨细胞因子的…

NOIp 的 p 是 painting 的 p!

哇还有连续剧。 作者在 CSP 后推完魔宴正在推 WA2。 Day -6 发现惊天理论:Day -3 最后的 ZR 有点娱乐赛,T1 是哈希表广告题,赛时裸 umap 拿了 90pts,赛后拿 umap 和 gp 卡了一万年卡不过,严肃学习 Dzb 牌哈希表,…

AWS云计算入门指南:从零到一,详解核心服务与免费套餐 - 教程

AWS云计算入门指南:从零到一,详解核心服务与免费套餐 - 教程2025-12-03 22:00 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !impor…

概率论直觉(二):方差与期望 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

图书馆管理系统项目冲刺 Day7

图书馆管理系统项目冲刺 Day7 一、站立式会议 照片: [插入Day6站立会议照片] 二、昨天已完成的工作 读者管理和个人中心完成 搜索优化和推荐系统实现 统计分析功能添加 三、今天计划完成的工作 何昊天: 实现系统设置…