1: 什么是函数指针
- 这个问题老生常谈了,不用理解的多么复杂,它其实就是一个特殊的指针,它用于指向函数被加载到的内存首地址,可用于实现函数调用。
- 听上有点像函数名,函数名也是记录了函数在内存中的首地址,加
()
就可以调用。 - 不错,不过函数指针和函数名还是有点区别的,他们虽然都指向了函数在内存的入口地址,但函数指针本身是个指针变量,对他做
&
取地址的话会拿到这个变量本身的地址去。 - 而对函数名做
&
取址,得到的还是函数的入口地址。如果是类成员函数指针,差别更加明显。
始终记住最大的两个不同点
- 既然他是指针,而且不是const的,那么他就是灵活可变的,通过赋值不同的函数来实现不同的函数调用。
- 然而他也有自己的限制(函数签名——返回值类型和参数类型),那不是和覆盖、多态实现的功能一样了么?额。。。要这么理解也行,但不全对
总结
上面说到函数指针的功能类似覆盖或多态,覆盖和多态更多体现的是对象自身的特征和对象之间的继承关联,而函数指针则没这么多讲究,他就是灵活。
函数指针不需要依附于对象存在,他可以用来解决基于条件的多个函数筛选,也可以处理完全无关的几个函数。
所以他的作用,什么封装性好、用于回调函数、实现多态等等,随便了,只有一条,符合他的函数签名并且可达。
1: 简单的函数指针:void (*f_ptr)()
这是定义了一个名为f_ptr的函数指针「变量」
给函数指针赋值:f_ptr = function;
function是一个已经定义的函数名(给函数指针赋值的时候,对应的函数签名(返回值和参数列表)必须是和他的相匹配的。)
using namespace std;
double cal_m1(int lines)
{
return 0.05 * lines;
}
double cal_m2(int lines)
{
return 0.5 * lines;
}
void estimate(int line_num, double (*pf)(int lines))
{
cout << "The " << line_num << " need time is: " << (*pf)(line_num) << endl;
}
int main()
{
int line_num = 10;
// 函数名就是指针,直接传入函数名
estimate(line_num, cal_m1);
estimate(line_num, cal_m2);
return 0;
}
// 打印结果
The 10 need time is: 0.5
The 10 need time is: 5
2:typedef void (*f_ptr)()
这是定义了一个名为f_ptr的函数指针「类型」,这个类型代表返回值为空,参数为空的函数指针类型
声明一个函数指针并赋值 :
typedef void (*f_ptr)();
f_ptr fp = function ; // void (*f_ptr)() = function;
using namespace std;
// 类型定义:声明函数指针
typedef int(*pfunc)(int x, int y);
int main()
{
auto func = [](int x, int y)->int {
return x + y;
};
pfunc p1 = nullptr; // pfunc 定义函数指针
p1 = func; //lambda表达式向函数指针转换
std::cout << p1(1, 2) << std::endl;
return 0;
}
// 打印值: 3
参考文献: