函数指针与回调函数(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;
}