文章目录 回调 可调用对象 函数指针作回调 函数对象作回调 函数对象的使用 std::function【C++11】 作回调使用 【C++11】Lambda表达式作回调 【C++11】bind对象作回调
回调
当发生某种事件时需要调用或触发另一个事件即为回调,回调的核心即为将可调用对象作为参数传递,在满足某种条件时执行。
可调用对象
可调用对象包括函数、函数指针、函数对象/仿函数【C++】、Lambda表达式【C++11】、bind对象【C++11】
函数指针作回调
int (*Callback)(int,int);
函数指针Callback指向一个返回值为int类型,传参为两个int类型的函数,例如int add(int x,int y);
// 定义回调函数类型(函数指针)
typedef int (*Callback)(int,int);// 回调事件(接受回调)
void Event(Callback cb,int x,int y) {std::cout<<cb(x,y)<<std::endl; // 触发回调
}// 实际回调
int My_Callback(int x,int y) {return x+y+100;
}int main() {int x{0};int y{0};cin>>x>>y;Event(My_Callback,x,y); // 注册回调return 0;
}
函数对象作回调
函数对象的使用
函数对象即仿函数,实际上是类中对于()运算符进行重载operator(),本质是对象调用其成员函数(成员方法)。
class MyPrint {
public:
//重载()运算符void operator()(string text) {cout << text << endl;}
};
class MyAdd {
public:int operator()(int a, int b) {return a + b;}
};
int main() {MyPrint my;my("你好");//my.operator()("你好");//函数对象即仿函数实质是对函数运算符()的重载MyAdd add;cout<<add(5, 5)<<endl;return 0;
}
std::function【C++11】
C++11引入的通用可调用对象包装器它可以存储、复制和调用任何可调用对象,作用其实类似于函数指针,只不过函数指针只适用于函数,而std::function适用于所有的可调用对象。 std::function<返回值类型(参数类型1, 参数类型2, …)>
//示例-存储普通函数
#include <iostream>
#include <functional>int add(int a, int b) {return a + b;
}int main() {std::function<int(int, int)> func = add; // 存储函数指针std::cout << func(2, 3); // 输出 5return 0;
}
作回调使用
函数对象作回调是整个对象被传递,而不仅仅是函数,可以携带自己的属性
#include<iostream>
#include<functional>
using namespace std;typedef std::function<int(int,int)> callback;// 实际回调
class My_Callback{public:int operator()(int x,int y){return x+y+other;}int other{100};//函数对象可以保存自己的属性
};// 回调事件(接受回调)
void Event(callback cb,int x,int y) {std::cout<<cb(x,y)<<std::endl; // 触发回调
}int main() {int x{0};int y{0};cin>>x>>y;My_Callback Callback;Event(Callback,x,y); // 注册回调return 0;
}
【C++11】Lambda表达式作回调
Lambda表达式实际上可以看作一段可调用的函数代码,具体使用方法可见文章C++11 Lambda表达式以及 C++11新特性 第9点,在此不再赘述。
//Lambda表达式作回调
#include<iostream>
#include<functional>
using namespace std;typedef std::function<int(int,int)> callback;// 回调事件(接受回调)
void Event(callback cb,int x,int y) {std::cout<<cb(x,y)<<std::endl; // 触发回调
}int main() {int x{0};int y{0};cin>>x>>y;// 实际回调函数(Lambda)auto Callback = [](int x,int y){return x+y+100;};Event(Callback,x,y); // 注册回调return 0;
}
【C++11】bind对象作回调
std::bind的使用
std::bind用于将函数和参数绑定成一个可调用对象,可以和std::function配合使用,绑定后的结果可以使用std::function存储
//std::bind的使用#include<iostream>
#include<functional>
using namespace std;int My_Callback(int x,int y) {return x+y+100;
}int main() {int x{0};int y{0};cin>>x>>y;auto Callback= std::bind(&My_Callback,x,y);std::cout<<Callback()<<std::endl;return 0;
}
作回调使用
#include<iostream>
#include <functional>
using namespace std;class My_Callback{public:int add(int x,int y){return x+y+other;}int other{100};//函数对象可以保存自己的属性
};int main() {int x{0};int y{0};cin>>x>>y;My_Callback Callback;//需要调用成员方法add,所以必须传this(即Callback)std::function<int(int,int)> callback = std::bind(&My_Callback::add,&Callback,std::placeholders::_1, std::placeholders::_2); //std::placeholders::_1, std::placeholders::_2即为占位符,表示有两个参数//等价于 std::function<int(int,int)> callback=[&Callback](int x,int y){return Callback.add(x,y);};std::cout<<callback(x,y)<<std::endl; /*也可直接绑定参数即:std::function<int()> callback = std::bind(&My_Callback::add,&Callback,x,y);//等价于 std::function<int()> callback=[&Callback,x,y](){return Callback.add(x,y);};std::cout<<callback()<<std::endl; */return 0;
}