C++:函数指针进阶(一):包含数据和函数的函数指针-创新互联

1:函数指针的背景

我们先简单聊一下函数指针的背景,具体使用请参考我的这篇博客

成都创新互联是一家专业提供平邑企业网站建设,专注与成都网站设计、成都网站建设、H5场景定制、小程序制作等业务。10年已为平邑众多企业、政府机构等服务。创新互联专业网站设计公司优惠进行中。

C++ :函数: 函数指针_hongwen_yul的博客-博客

假设现在有这样一段代码:C/C++中可以使用指针指向一段代码,这个指针就叫函数指针,假设有这样一段代码、

// main.cpp
#includeint func(int a) {

    return a+1;
}


int main(){

    int (*f)(int) = func;
    printf("%p",f);
}

// 打印结果 :400526

我们定义一个函数 func() ,然后使用指针变量 f 指向该函数,然后打印该变量f 指向的地址,代码是很简单的,然后我们编译一下,看下编译后生成的指令,接下来我们重点关注fuc 函数:

可以看到,编译好的函数 func 位于地址 ox400526,然后我们运行下编译好的程序,发现输出的数据和编译后的地址是一致的,这个指针变量保存了函数func 的机器指令。

所以说明:函数指针本质上也是一个指针,只不过这个指针指向的不是内存中的一段数据,而是内存中的一段代码。

有的同学可能会有疑问,:为什么编译器在生成可执行文件时就知道函数 func 存放在内存地址 0x400526上了?这不是应该是程序被加载到内存后开始运行时,才能确定的吗?

答案就在函数指针:可以把一段代码当做一个变量传来传去,这个变量保存了这段代码地址,它的主要用途之一就是 回调函数,关于回调函数,你可以参考我的这篇文章。

C++:函数:回调函数:还不懂回调函数来捶我_hongwen_yul的博客-博客q​​​​​​回调函数------函数指针https://blog.csdn.net/u013620306/article/details/128009205?spm=1001.2014.3001.5501

其实回调函数就是这样的

2:函数指针的衍生

上面我们说到,可以定义一个指针变量来保存函数地址,但是了,假如我们我们的场景在复杂点:

我们依然需要在模块A中定义函数,同时运行模块A 需要依赖模块B产生的数据,然后将模块A定义的函数和模块B产生的数据一并传递给模块C来调用,就像这样:

很显然单纯的函数指针已经不够用了,因为函数指针只是单纯的指向了内存中的一段代码,但是我们不仅需要将内存的一段代码同时也需要内存中的一块数据,一并传递给模块C。

那么如何实现上面的功能了? 你可以定义一个结构体,将代码和数据打包起来、

typedef void (*func) (int);

struct closure{
func f;
int arg;    
};

我们将这个结构体命名为 :closure 这个结构体中包含两部分

  1. 一个指向代码的指针变量
  2. 一个保存数据的变量 

这样,我们在模块A 为指针变量赋值,在模块B为保存数据的变量赋值,然后将此结构体传递给模块C ,模块C中可以这样使用。

void run(struct functor func) {
func->f(func->arg);
}

closure既包含了一段代码也包含了这段代码使用的数据,这里的数据称为context (函数运行依赖的数据),这个技术就是:Functor 。(就是说:单纯的函数指针并没有捕捉上下文的能力,这里的上下文就是指代码依赖的数据,你不得不自己动手构造一个结构体用来存储代码依赖的上下文。)

有的同学又会问了:为什么不用函数指针来指向对象的成员函数,这是因为函数指针没有办法捕捉 this (指向对象的指向) 这个上下文 。 (原因我后面在讲,这个不是本文的重点)

3:std::Function
  1. 所以 std::function的作用本质和我们刚刚定义的结构体区别不大。
  2. 利用std::function你不但可以保存一段代码,同时也可以保存必要的上下文,然后在合适的地方基于上下文调用这段代码。
  3. 同时std::function 更加通用,你可以用其存储任何可以被调用的对象(callable object)只要有正确的函数签名就可以了。

好像还是不能理解?没关系,我们一步一步带领大家去理解,大家先对 std::Function有一个概念性的认识。

3.1:先想一想:C++怎样定义指向对象成员函数的指针

参考我的这篇博文

C++:函数指针进阶二:指向对象成员函数的指针_hongwen_yul的博客-博客

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


网站栏目:C++:函数指针进阶(一):包含数据和函数的函数指针-创新互联
网站URL:http://ybzwz.com/article/dogdop.html