Skip to content

函数指针与回调函数 ​

函数指针是一个变量,可存储函数的地址,在程序执行的不同时间可指向不同的函数。

定义函数指针 ​

cpp
// 函数指针定义的一般形式
return_type (*pointer_name)(parameter_types);

// 举例:函数指针
long (*func_ptr)(long*, int);	// 指向一个返回long类型函数的指针变量
  • 指针变量名称:func_ptr
  • 返回类型:long
  • 参数类型:long*、int

函数指针的使用 ​

cpp
long func(long*, int);

// 1. 函数指针的定义
// 在声明指针时总数应该进行初始化:将函数指针初始化为 nullptr 或 某个函数的名称
long (*func_ptr)(long*, int) { func };	// 不推荐
// 函数名称标识符可以隐式转换为 函数指针 或 函数地址,但为了提高可读性,函数取地址时应显式使用 & 运算符
long (*func_ptr)(long*, int) { &func }; // 推荐
// 等价于
long (*func_ptr)(long*, int);   // 1. 声明函数指针变量
func_ptr = &func;               // 2. 赋值(指向具体函数)


// 使用 auto:使定义函数指针更简单
auto func_ptr = func;
auto* func_ptr = func; // 一样效果,但更强调 func_ptr 是个指针

// 2. 函数指针的使用
long data[] {23, 34, 22, 56, 87, 12, 57, 76};
func_ptr(data, std::size(data));

函数指针的类型别名 ​

定义类型以便复用。

cpp
bool (*string_compare)(const std::string&, const std::string&);

// typedef 旧式写法
typedef bool (*StringCompare)(const std::string&, const std::string&); // 缺点:无法定义别名模板


// using 声明 新式写法
/***** 为函数指针的类型起别名的过程 *****/
// 1. 丢弃变量名称 string_compare,得到变量的类型
bool (*)(const std::string&, const std::string&);
// 2. 使用 using 关键字为该类型定义别名
using StringCompare = bool (*)(const std::string&, const std::string&);
// 3. 声明 string_compare 参数
StringCompare string_compare;

/***** 为模板函数指针定义别名 *****/
template <typename T>
using Comparison = bool (*)(const T&, const T&); // 生成类型别名的模板
// 使用该类型别名的模板
Comparison<std::string> string_compare { &func };

回调函数 ​

回调函数:把一个函数当作参数传给另一个函数,然后在适当的时候“调用”这个函数,作为参数传递的函数称为回调函数。

高阶函数:接收另一个函数作为实参的函数;

回调函数的目的:让调用者自己决定逻辑的一部分。

cpp
// 1. 定义:写一个满足签名的普通函数
// 回调函数:处理数字
int doubleValue(int x) {
    return 2 * x;
}

// 2. 声明:int (*func)(int) 这样声明函数指针
// 高阶函数:接受一个处理函数(回调)
void processAndPrint(int x, int (*func)(int)) {
    int result = func(x);  // 回调函数被调用
    cout << result << endl;
}

// 3. 传入并调用:把函数名传进去,再用 func(x) 调用
processAndPrint(5, doubleValue);  // 输出 10