文章目錄 回調 可調用對象 函數指針作回調 函數對象作回調 函數對象的使用 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;
}