引子
函数指针的一个最大的好处在于它可以像我们常用的变量一样在代码中进行传递。它的本质就是用一个变量去接收函数所在内存的地址。
普通的函数调用
void functionTest()
{
std::cout << "Hello function!!!" <<std::endl;
}
int main()
{
functionTest();
}
函数指针类型
用auto关键字定义接收函数地址
auto helloFuntion = &functionTest;
helloFuntion();
这里helloFuntion 的类型为:
void (*)()
或者
void (*)(void)
这个是一类函数类型的声明,返回值为void,没有返回值。中间()表名是一个指针类型, 最后的()表示没有参数。这个就是定义了一种变量,没有返回值没有参数的这一类函数地址类似于int 。
函数指针普通使用
常规用法
用void (*)()
声明一个变量:
void (*helloFuntion)();//声明一个变量,类型为void (*)()
例子:
void (*helloFuntion)() = &functionTest;//
helloFuntion();
也可以用typedef或者using 来对函数指针类型进行别名声明:
typedef
typedef void (*helloFuntionType)();//起别名helloFuntionType
helloFuntionType helloFuntion = &functionTest;
helloFuntion();
using
using helloFuntionType = void (*)();
helloFuntionType helloFuntion = &functionTest;
helloFuntion();
作为参数传给函数的例子
#include <vector>
#include <iostream>
void printValue(int value)
{
std::cout << "value: " << value << std::endl;
}
/**
*
*/
void ForEach(std::vector<int>& values, void(*func)(int))
{
for(int value : values)
{
func(value);
}
}
int main()
{
std::vector<int> values {1, 3, 5, 7, 8 ,9};
ForEach(values, printValue);
return 0;
}
上面例子也可以用lamda表达式进行改写,更简洁:
int main()
{
std::vector<int> values {1, 3, 5, 7, 8 ,9};
ForEach(values, [](int value){std::cout << "value: " << value << std::endl;});
return 0;
}
总结:
说实话,个人觉得这种C风格的函数指针,语法总有些怪怪的,不易于理解。如果你是一个现代C++(modern C++)工程师,那么你更应该倾向于使用lamda和bind而不是使用老式的C函数指针。