C++函数指针是指向函数的指针变量,它存储的是函数在内存中的入口地址,通过函数指针可以直接调用对应的函数,而回调函数则是通过函数指针将函数作为参数传递,实现调用方和被调用方的解耦。

C++函数指针的基础定义与使用
函数指针的声明语法
函数指针的声明需要匹配目标函数的返回类型和参数列表,基本语法为:返回类型 (*指针变量名)(参数类型列表)。例如声明一个指向返回int、接收两个int参数的函数的指针,写法如下:
// 声明函数指针,指向返回int、参数为两个int的函数 int (*func_ptr)(int, int);
函数指针的赋值与调用
函数名本身代表函数的入口地址,可以直接赋值给同类型的函数指针,之后通过指针调用函数有两种方式,一种是直接用*指针名解引用调用,另一种是直接用指针名调用,两种写法等价。
#include <iostream>
using namespace std;
// 定义两个符合函数指针类型的函数
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
int main() {
// 声明函数指针
int (*func_ptr)(int, int);
// 赋值函数地址
func_ptr = add;
// 调用方式1:解引用调用
cout << "add result: " << (*func_ptr)(3, 2) << endl;
// 调用方式2:直接通过指针调用
cout << "add result: " << func_ptr(3, 2) << endl;
// 重新赋值指向sub函数
func_ptr = sub;
cout << "sub result: " << func_ptr(5, 3) << endl;
return 0;
}
函数指针作为回调函数参数
回调函数的核心是将函数指针作为参数传递给另一个函数,当被调用函数执行到特定逻辑时,通过传入的函数指针调用对应的函数,实现逻辑的动态扩展。
简单回调函数示例
下面的示例中,calculate函数接收两个操作数和函数指针作为参数,具体执行加法还是减法由传入的函数指针决定。
#include <iostream>
using namespace std;
// 定义回调函数类型
typedef int (*CalcFunc)(int, int);
// 加法函数
int add(int a, int b) {
return a + b;
}
// 减法函数
int sub(int a, int b) {
return a - b;
}
// 接收函数指针作为参数的函数,即使用回调函数的函数
int calculate(int a, int b, CalcFunc func) {
return func(a, b);
}
int main() {
int x = 10, y = 5;
// 传入add函数作为回调
cout << "add: " << calculate(x, y, add) << endl;
// 传入sub函数作为回调
cout << "sub: " << calculate(x, y, sub) << endl;
return 0;
}
带上下文的回调函数实现
如果需要回调时传递额外的上下文信息,可以结合结构体或者void指针实现,下面的示例通过void指针传递上下文数据。
#include <iostream>
#include <cstring>
using namespace std;
// 回调函数类型,接收void*上下文参数
typedef void (*CallbackFunc)(void* ctx);
// 回调处理函数
void process_data(CallbackFunc callback, void* ctx) {
// 执行处理逻辑
cout << "process data start" << endl;
// 调用回调函数,传入上下文
callback(ctx);
cout << "process data end" << endl;
}
// 具体回调函数实现
void print_info(void* ctx) {
char* info = (char*)ctx;
cout << "callback info: " << info << endl;
}
int main() {
char ctx_data[] = "test context data";
process_data(print_info, ctx_data);
return 0;
}
函数指针数组的使用
函数指针数组可以存储多个同类型的函数指针,适合实现命令分发、状态机等功能,通过数组下标快速调用对应的函数。
#include <iostream>
using namespace std;
// 函数声明
void func1() { cout << "call func1" << endl; }
void func2() { cout << "call func2" << endl; }
void func3() { cout << "call func3" << endl; }
int main() {
// 定义函数指针数组,存储三个函数的地址
void (*func_arr[])() = {func1, func2, func3};
int arr_size = sizeof(func_arr) / sizeof(func_arr[0]);
// 遍历数组调用函数
for (int i = 0; i < arr_size; i++) {
func_arr[i]();
}
return 0;
}
注意事项
- 函数指针的类型必须和指向的函数完全匹配,包括返回类型和所有参数类型,否则会导致编译错误或者运行时异常。
- 普通成员函数和普通函数不同,成员函数指针的声明和调用需要结合对象实例,不能直接赋值给普通函数指针。
- 使用函数指针传递回调函数时,要确保函数的作用域有效,避免传入已经销毁的函数的地址。