使用类的成员函数来实现回调函数

目标读者:可以理解回调函数的含义函数


把类的成员函数做为回调函数有三个步骤:this

  1. 实现这个成员函数,
  2. 对这个函数进行绑定
  3. 将绑定好的函数指针传给调用函数。

1、添加头文件

#include <functional>

2、typedef一个函数指针类型

这一步是为了方便地获得所需的函数指针变量spa

typedef std::function<void (int,int)> Fun;//注意void与()之间是空格而不是‘,’

typedef std::function<返回类型 (参数一,参数二)> 函数指针类型名称.net

3、函数绑定

要想直接将一个类成员函数设置为一个回调函数,而不是使用静态成员函数,须要用到std::bind。指针

Fun fun = bind(&Test::callback, this,placeholders::_1,placeholders::_2);

回调函数指针类型 函数指针变量 = bind(&类::回调函数, 类指针,参数占位符);code


》关于placeholders

placeholders域在这里起到占位符的做用,指明该参数是调用者在使用回调函数时传入的第几个参数。例如placeholders域下的_1、`_2分别表明调用者传入的第一个、第二个参数。blog

举个例子get

读者能够先看完下面回调函数的代码实现后再回过来看这个例子,方便理解。回调函数

callback是一个有两个参数的回调函数。实现一个做差的功能。io

void Test::callback(int a,int b)
{
    printf("%d - %d = %d", a, b, a - b);
}

绑定时,设置把传入的第2个参数传给变量a,把传入的第1个参数传给变量b。

Fun fun = bind(&Test::callback,this,placeholders::_2,placeholders::_1);

调用者在实际调用时,把值2传给变量a,把值1传给变量b。

fun(1,2);//fun(placeholder::_1, placeholder::_2);

计算结果:

2 - 1 = 1

绑定时不只能够传入占位符,还能够直接传入变量。例如

int x = 5;
Fun fun = bind(&Test::callback,this,placeholders::_2,x);
fun(1,2);

输出:

2 - 5 = -3

4、代码实例

在这个代码实例中,回调函数,绑定函数和调用函数都放在一个类里面,在实际项目中绑定函数和回调函数通常处在一个类中,而调用函数则存在于其余的类中。

#include <stdio.h>
#include <functional>

using namespace std;

class Test
{
public:
    
    typedef std::function<void (int,int)> Fun;//typedef一个函数指针
    
    void callback(int a,int b)/*回调函数*/
    {
        printf("%d+%d = %d",a,b,a+b);
    }
    
    void bind()/*绑定*/
    {
        Fun fun = bind(&Test::callback, this,placeholders::_1,placeholders::_2);
        call(1, fun);
    }
    void call(int a,Fun f)/*调用者*/
    {
        f(a,2);
    }
    
};


int main()
{
    
    Test test;
    test.bind();
    
    return 0;
}

输出结果:

1+2=3

5、参考资料:

一、std::function与std::bind 函数指针 (实现回调函数的不一样方式)

二、cplusplus:std::placeholders (placeholders的用法)

相关文章
相关标签/搜索