在C++中可以使用指针指向一段代码,这个指针就叫函数指针,假设有下面一段代码
#include
int func(int a) {
return a+1;
}
void main()
{
// 定义一个函数,然后使用指针变量f指向该函数
int (*f)(int) = func;
printf("%p\n",f);
}
我们编译上述代码,得到 汇编和机器码
得到的地址为:这个地址正好是 编译好的函数 func 所在的地址 : ox401156
而函数指针打印的地址也是这个。
实际上函数指针本质也是一个指针,只不过这个指针指向的不是内存中的一段数据而是内存中的一段代码。
为什么编译器在生成可执行文件时就知道函数func存放在内存地址0x400526上呢?这不应该是程序被加载到内存后开始运行时才能确定的吗?
函数指针的作用是可以把一段代码当做一个变量传来传去,它的主要作用就是回调函数。
如:关于回调函数其实是在A模块定义,在B模块被调用,就像这样。
这是一个很简单的场景,但是我们设想一下,有如下场景:
我们需要在模块A 中定义函数,同时函数A的运行需要依赖B模块,然后将模块A的函数和 模块B的数据一并传给 C模块来调用,就像这样 :
typedef void (*func) (int);
struct closure
{
func f;
int arg;
}
void run(struct closure func)
{
func->f(func->arg);
}
// 即,closure 既包含了一段代码也包含了这段代码使用的数据,这里的数据也被称为 context(上下文)或者
// environment(环境), 其实不管怎么称呼,它就是函数运行依赖的数据。
上述步骤中,这正是 std::functional 的目的所在。