c-style 函数指针
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数(类),当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应
回调函数机制:
1、定义一个函数(普通函数即可);
2、将此函数的地址注册给调用者;
3、特定的事件或条件发生时,调用者使用函数指针调用回调函数。
注:为什么要特定事件或条件发生?不应该随时都可以调用回调函数吗?
以下是回调函数的两种使用方式(简单理解):
#include <stdio.h>
typedef int(*callback)(int,int);
int add(int a,int b,callback p){
return (*p)(a,b);
}
int add(int a,int b){
return a+b;
}
int main(int argc,char *args[]){
int res = add(4,2,add);
printf("%d\n",res);
return 0;
}
在这个例子中,可以看到,我们定义了一个callbak的函数指针,参数为两个int,返回值为int,通过调用函数地址来进行简单的相加运算。
#include <stdio.h>
typedef int (callBack)(const void *buffer,size_t size,char *p_out);
void callFunc(callBack *consume_bytes, char *p_out) {
printf("callFunc\n");
const void *buffer = NULL;
consume_bytes(buffer,0,p_out); //传入值可以随便填
}
int callBackFunc(const void *buffer, size_t size, char *p_out){
printf("callBackFunc\n");
memset(p_out,0x00,sizeof(char)*100);
strcpy(p_out,"encoderCallback:this is string.");
return 1;
}
int main(int argc,char *args[]){
char p_out[100];
callFunc(callBackFunc,p_out);
printf("%s\n",p_out);
return 0;
}
std::function std::bind
std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。
std::bind()函数的意义就像它的函数名一样,是用来绑定函数调用的某些参数的。
#include <iostream>
#include <functional> // fucntion/bind
class ProgramA {
public:
void FunA1()
{
printf("I'am ProgramA.FunA1() and be called..\n");
}
//回调次函数
int FunA2(std::string str,int num,int num2)
{
printf("I'am ProgramA.FunA2() and be called..\n");
std::cout<<str<<std::endl;
return num+num2;
}
static void FunA3()
{
printf("I'am ProgramA.FunA3() and be called..\n");
}
};
class ProgramB {
typedef std::function<void ()> CallbackFun;
//回调函数类型
typedef std::function<int (int,int)> CallBackFun2;
public:
ProgramB()
{
}
ProgramB(CallBackFun2 fun)
{
//设置回调函数
callback=fun;
}
void FunB1(CallbackFun callback)
{
printf("I'am ProgramB.FunB1() and be called..\n");
callback();
}
void FunB2()
{
printf("I'am ProgramB.FunB2() and be called..\n");
//.....
int num1=1;
int num2=2;
//触发回调
std::cout<<callback(num1,num2)<<std::endl;
}
private:
CallBackFun2 callback;
};
void normFun() { printf("I'am normFun() and be called..\n"); }
int main(int argc, char **argv) {
ProgramA PA;
PA.FunA1();
printf("\n");
ProgramB PB;
//普通函数指针
PB.FunB1(normFun);//OK
printf("\n");
//静态成员函数
PB.FunB1(ProgramA::FunA3);//OK
printf("\n");
//普通成员函数,普通成员函数隐藏着一个this参数(第一参数)
PB.FunB1(std::bind(&ProgramA::FunA1, &PA));//OK
//std::function<int (int,int)> CallBack=std::bind(&ProgramA::FunA2, &PA,"执行回调函数",std::placeholders::_1,std::placeholders::_2);
//ProgramB PB2(CallBack);
//OK
//初始化时设置回调函数
ProgramB PB2(std::bind(&ProgramA::FunA2, &PA,"执行回调函数",std::placeholders::_1,std::placeholders::_2));
//此处理函数处理完,调用回调函数
PB2.FunB2();
//OK 同上
}
using namespace std;
void output(int a, int b, int c) {
cout << a << " " << b << " " << c;
}
int main()
{
auto func = bind(output, placeholders::_2, placeholders::_1, placeholders::_3);
func(1, 2, 3); //结果 2 1 3
return 0;
}
//初始化时设置回调函数
//int FunA2(std::string str,int num,int num2)
ProgramB PB2(std::bind(&ProgramA::FunA2, &PA,"执行回调函数",std::placeholders::_1,std::placeholders::_2));
//此处理函数处理完,调用回调函数
PB2.FunB2();
//OK 同上
//std::placeholders::_1,std::placeholders::_2 指的是剩余空位