正常回调函数使用的是普通函数或者静态函数,而成员函数因为会在参数列表最前面插入一个 this 指针,所以导致直接使用会报错。成员函数想要被调用需要使用特殊的操作方法。

1. 接收成员函数作为参数

需要使用 std::function 来预先确定成员函数的返回值和参数列表。具体代码如下:

typedef std::function<void(int,int)> Fun;

class B{
    public:
        void call(int a,Fun f)
        {
            f(a,2);
        }
};

2. 把具体的成员函数配置下去

需要使用 std::bind 来把具体的成员函数和参数位置一起生成和上一步对应的,然后才能配置过去。具体代码如下:

using namespace std::placeholders;
class Test{
public:
    void callback(int a,int b)
    {
        cout<<a<<"+"<<b<<"="<<a+b<<endl;
    }

    void bind()
    {
        Fun fun=std::bind(&Test::callback,this,_1,_2);
        B b;
        b.call(1,fun);
    }

};

完整例子如下:

#include <iostream>  
#include <functional>  
using namespace std;  

typedef std::function<void ()> fp;  
void g_fun()  
{  
    cout<<"g_fun()"<<endl;  
}  
class A  
{  
public:  
    static void A_fun_static()  
    {  
        cout<<"A_fun_static()"<<endl;  
    }  
    void A_fun()  
    {  
        cout<<"A_fun()"<<endl;  
    }  
    void A_fun_int(int i)  
    {  
        cout<<"A_fun_int() "<<i<<endl;  
    }  

    //非静态类成员,因为含有this指针,所以需要使用bind  
    void init()  
    {  
        fp fp1=std::bind(&A::A_fun,this);  
        fp1();  
    }  

    void init2()  
    {  
        typedef std::function<void (int)> fpi;  
        //对于参数要使用占位符 std::placeholders::_1  
        fpi f=std::bind(&A::A_fun_int,this,std::placeholders::_1);  
        f(5);  
    }  
};  
int main()  
{  
    //绑定到全局函数  
    fp f2=fp(&g_fun);  
    f2();  

    //绑定到类静态成员函数  
    fp f1=fp(&A::A_fun_static);  
    f1();  

    A().init();  
    A().init2();  
    return 0;  
}

参考: https://blog.csdn.net/hyp1977/article/details/51784520 https://blog.csdn.net/this_capslock/article/details/38564719 https://blog.csdn.net/hanxiucaolss/article/details/89500738 https://www.jianshu.com/p/8b6de1e99fc2

标签: callback, hook

添加新评论