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

函数指针与回调函数(c++)

函数和函数指针

void hello(int x) {std::cout << "Hello " << x << std::endl;
}

这个函数叫 hello,它有一个地址(就像房间有门牌号一样)。

我们想用一个变量来保存这个地址,这个变量就是“函数指针”。
给函数指针赋值

void hello(int x) {std::cout << "Hello " << x << std::endl;
}int main() {void (*ptr)(int);     // 定义一个函数指针ptr = hello;          // 把函数 hello 的地址赋给 ptrptr(5);               // 调用 ptr 指向的函数,等价于 hello(5)return 0;
}

✅ 关键点
hello 是函数名,它本身就表示“函数的地址”
ptr = hello; 就是把 hello 的地址存到 ptr 中
ptr(5); 就是“调用 ptr 指向的那个函数”,和 hello(5) 效果一样

加上 typedef

现在我们觉得 void (*ptr)(int) 太长、太难写,想给它起个简单名字。

typedef void (*Callback)(int);

这行代码的意思是:

“从现在起,Callback 是一个类型别名,它等价于 void (*)(int) 这种函数指针类型。”
用新名字来定义变量

#include <iostream>// 定义一个新类型:Callback
typedef void (*Callback)(int);// 一个符合这个类型的函数
void greet(int x) {std::cout << "Hello: " << x << std::endl;
}int main() {Callback ptr;      // 等价于 void (*ptr)(int);ptr = greet;       // 把函数地址赋给 ptrptr(5);            // 调用 greet(5)return 0;
}

回调函数

#include <iostream>// 1. 定义回调函数的类型:返回 void,参数是 int
typedef void (*Callback)(int);// 2. 一个普通函数,我们将用它作为回调
void myCallback(int x) {std::cout << "回调被调用,x = " << x << std::endl;
}// 3. 主函数:它接收一个“回调函数”作为参数
void doWork(int data, Callback cb) {// 做一些工作...std::cout << "正在处理数据..." << std::endl;// 工作完成,调用回调函数cb(data);  // 这就是“回调”:调用你传进来的函数
}// 4. 主程序
int main() {// 调用 doWork,并把 myCallback 作为回调传进去doWork(100, myCallback);return 0;
}

再举一个简单的例子:

#include <iostream>// 1. 定义一个回调函数类型(可选,用 typedef 简化)
//typedef void (*Callback)(int);// 或者用更现代的写法(C++11 起):
using Callback = void (*)(int);// 2. 一个实际的回调函数(打印数字)
void printNumber(int value) {std::cout << "收到数值: " << value << std::endl;
}// 3. 一个接受回调函数的函数
void doSomething(int x, Callback callback) {std::cout << "正在处理..." << std::endl;// 做一些事情...// 调用回调函数callback(x);
}// 4. 主函数
int main() {// 传递 printNumber 作为回调doSomething(42, printNumber);return 0;
}

通过function<>的例子:

#include <iostream>
#include <functional>// 使用别名简化类型(可读性更好)
using Callback = std::function<void(int)>;void doSomething(int x, const Callback& callback) {std::cout << "正在处理..." << std::endl;// 可选:检查 callback 是否有效(防止空调用)if (callback) {callback(x);} else {std::cerr << "警告:回调函数为空!" << std::endl;}
}int main() {doSomething(42, [](int value) {std::cout << "Lambda 回调: " << value << std::endl;});return 0;
}

std::function<void(int)>
是一个 C++ 标准库提供的“通用可调用对象包装器”,它可以保存、复制、调用任何“和 void(int) 类型匹配的可调用对象”。

#include <iostream>
#include <functional>// 定义一个类型别名,简化写法
using Callback = std::function<void(int)>;// 1. 普通函数
void normal_func(int x) {std::cout << "普通函数: " << x << std::endl;
}// 2. Lambda 表达式(匿名函数)
auto lambda = [](int x) {std::cout << "Lambda: " << x << std::endl;
};// 3. 函数对象(仿函数)
struct Functor {void operator()(int x) {std::cout << "函数对象: " << x << std::endl;}
};int main() {Callback cb;// ✅ 都可以赋值给 std::function<void(int)>cb = normal_func;     // 普通函数cb(1);cb = lambda;          // Lambdacb(2);cb = Functor();       // 函数对象cb(3);return 0;
}
http://www.dtcms.com/a/349966.html

相关文章:

  • 厚铜pcb的工艺流程与制造工艺
  • AI创业公司:Freya 金融语音AI Agent
  • 猴车安全新保障:AI摄像机智能监测人员乘坐合规性
  • 算法 --- 双指针
  • 日语学习-日语知识点小记-构建基础-JLPT-N3阶段(19):文法复习+单词第7回1
  • 【C++高并发内存池篇】ThreadCache 极速引擎:C++ 高并发内存池的纳秒级无锁革命!
  • 【51单片机固定按键占空比】2022-11-12
  • 曲面法向量的数学推导与 SymPy 实现
  • 基于MATLAB长时间序列遥感数据处理及在全球变化、物候提取、植被变绿与固碳分析;长时序NDVI/LAI/GPP产品预处理
  • 音视频学习(五十七):RTSP信令交互流程
  • 1424. 对角线遍历 II
  • “Datawhale AI夏令营--coze空间
  • Java多线程常见误区与最佳实践总结
  • Spring拦截器中@Resource注入为null的问题
  • Github热门开源项目榜单 - 2025年07月
  • 【c++】leetcode300 最长递增子序列
  • 二、添加3D形状
  • Springboot应用如何与SkyWalking集成,并使用Docker进行发布
  • 深入理解Linux进程程序替换:从原理到实践
  • Elasticsearch JVM调优:核心参数与关键技巧
  • Git克隆时遇到“Filename too long“错误的完美解决方案
  • 代理设计模式
  • 俄罗斯情报机构推出新型安卓恶意软件,伪装成杀毒软件
  • SciPy科学计算与应用:SciPy入门与应用-科学计算与NumPy协同实践
  • 工业异常检测大模型(1)数据集、方法
  • 【git使用场景】本地仓库与远程仓库存在独立历史
  • Vulkan 学习路线图
  • Git 怎么仓库迁移?error: remote origin already exists.怎么解决
  • 定时器的原理
  • TensorFlow 深度学习 | Dataset API 数据读取详解