函数指针与回调函数
函数指针是一个变量,可存储函数的地址,在程序执行的不同时间可指向不同的函数。
定义函数指针
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