在其他函数中通过函数指针调用该函数的过程称为回调,即通过传参的方式将函数地址传递给其他函数,然后在其他函数中使用该函数,该函数被叫做回调函数。
一、C中回调函数使用
回调函数主要是利用函数指针实现的,函数指针与一般指针一样定义,不过需要明确返回值类型与形参类型int(*callbackfun)(int, int),调用函数形式如下,、,
void fun(int(*callbackfun)(int, int), int a, int b)
{
callbackfun(a,b);
}
为了使用方便可以利用typede将函数指针起个别名,typedef 返回值类型 (*指针名) (参数列表),增加typedef int(*callbackfun)(int, int)。修改后实例代码如下:
/*test.h*/
#include<iostream>
using namespace std;
typedef int(*callbackfun)(int, int,int);
void funAdd(callbackfun pf, int a=0, int b=0,int c=0)
{
cout << pf(a, b,c) << endl;
}
/*test.cpp*/
#include"test.h"
int add(int a, int b,int c)
{
return a + b;
}
void main()
{
funAdd(add, 1, 2);
}
二、C++回调函数使用
如果调用函数是类的成员函数,由于隐式this指针的存在,形参数量不匹配,所以注册使用回调函数会失败。所以一般C++中回调函数通过以下方式使用。
1.使用全局函数
以使用全局函数作为回调函数,实现在类中对类外部的函数的调用。C++中,全局函数的显示的函数参数就是它实际的函数的形参个数,所以全局变量其本身就不带有this指针,所以可以作为C++类成员函数的回调函数使用。
#include <iostream>
typedef void(*processFun)(int value,void* contex);
void resgisProcessFun(processFun fun,int value,void* contex)
{
fun(value,contex);
}
void process1(int value,void* contex)
{
std::cout<<"process "<<value<<std::endl;
}
class test
{
private:
int mValue;
public:
test() {}
~test() {}
static void process2(int value,void* contex)
{
test *t=(test *)contex;
if(t!=nullptr)
{
t->getValue(value);
}
}
void printFun(int value)
{
resgisProcessFun(process1,value,this);
}
};
int main(int argc, char *argv[])
{
test t;
t.printFun(20);
return 0;
}
2.使用静态成员函数
静态成员函数不使用this指针作为隐含参数,这样就可以作为回调函数了。静态成员函数具有两大特点:其一,可以在没有类实例的情况下使用;其二,只能访问静态成员变量和静态成员函数,不能访问非静态成员变量和非静态成员函数。使用类成员函数作为回调函数的目的就是为了访问所有的成员变量和成员函数,通过void *contex传一个类指针参数到静态成员函数中,通过这个类指针,如Sensor *sen=(Sensor *)contex,然后在回调函数中通过该指针就可以访问所有成员变量和成员函数了。
#include <stdio.h>
#include <iostream>
#include <math.h>
typedef struct _DataInfo
{
double height;
double length;
double width;
}stDataInfo;
typedef void(*callbackFun)(stDataInfo *data, void* contex);
void registHeightCallback(callbackFun callback, stDataInfo *data, void* contex)
{
if(NULL==callback&&NULL==data)
{
return;
}
callback(data,contex);
}
class Sensor
{
private:
stDataInfo *mData;
public:
Sensor(stDataInfo *data){mData=data;}
~Sensor(){}
static void onHeight(stDataInfo *data, void* contex)
{
Sensor* sen = (Sensor*)contex;
if(sen)
{
data->height=data->height+sen->mData->height;
sen->getHeight(data);
}
}
void print(stDataInfo *data)
{
registHeightCallback(onHeight, data, this);
}
void getHeight(stDataInfo *data)
{
std::cout << "rectangle height= " << data->height << std::endl;
}
};
int main(int argc, char* argv[])
{
stDataInfo data;
Sensor sens(&data);
data.length = 7.8;
data.height = 7.8;
data.width = 7.8;
sens.print(&data);
return 0;
}