昨天手動(dòng)binding C++的回調(diào)到Lua的時(shí)候撩独,用到了lambda表達(dá)式敞曹。今天專門看了一下cocos2dx的回調(diào)操作。都是個(gè)人筆記综膀,有問題歡迎指正澳迫, 不負(fù)任何法律責(zé)任,-_-
參考文章剧劝, 果凍想
1. 首先也是從這幾個(gè)回調(diào)開始看
#define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
#define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
#define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
#define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)
全是關(guān)于std::bind的宏定義橄登。因?yàn)閏ocos2dx中只會用到綁定成員函數(shù)的情況,所以讥此,這里只看一下拢锹,綁定成員函數(shù)的用法。
2.簡單看一下std::bind的源碼萄喳,在functional.h的頭文件中卒稳。
// TEMPLATE FUNCTION bind (implicit return type)沒有返回值
template<class _Fx,
class... _Types> inline
_Binder<_Unforced, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args)
{ // bind a callable object with an implicit return type
return (_Binder<_Unforced, _Fx, _Types...>(
_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...));
}
// TEMPLATE FUNCTION bind (explicit return type)有返回值的
template<class _Ret,
class _Fx,
class... _Types> inline
_Binder<_Ret, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args)
{ // bind a callable object with an explicit return type
return (_Binder<_Ret, _Fx, _Types...>(
_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...));
}
會發(fā)現(xiàn)下面還有一個(gè)枚舉,是關(guān)于參數(shù)占位符的枚舉他巨,一共20個(gè)充坑,所以用std::bind最多支持20個(gè)參數(shù)的函數(shù)的綁定。
3.綁定成員函數(shù)
這里主要是看綁定成員函數(shù)的基本用法:
首先染突,我有一個(gè)類捻爷,需要一個(gè)std::function的參數(shù)
#include<iostream>
#include <functional>
class MyClass
{
public:
typedef std::function<void(std::string)> myCallBack;
MyClass(std::string name);
~MyClass();
std::string getName();
void setName(std::string name);
void printInfo();
void setCallBack(myCallBack callBack); //需要一個(gè)std::function的方法
private:
std::string _name;
myCallBack _callBack;
};
然后看一下調(diào)用setCallBack的方法:
auto myClass = MyClass("12121");
myClass.setCallBack(std::bind(&HelloWorld::myClassCallBack/*函數(shù)名*/, this/*調(diào)用者*/, std::placeholders::_1/*參數(shù)*/));
因?yàn)閙yClassCallBack需要一個(gè)參數(shù),所以這里草穿進(jìn)去一個(gè)參數(shù)占位符份企,就可以接受調(diào)用過程中實(shí)際傳過來的參數(shù)了役衡。如果有多個(gè)參數(shù),就需要多個(gè)參數(shù)占位符薪棒。這里的參數(shù)占位符也可以替換成這種:
myClass.setCallBack(std::bind(&HelloWorld::myClassCallBack, this, "zzz test!!"));
這樣的話手蝎,下面的myClassCallBack中傳進(jìn)來的就是"zzz test!!",下面是成員函數(shù):
void HelloWorld::myClassCallBack(std::string str)
{
CCLOG("=============== %s", str.c_str());
}
4.綁定非成員函數(shù)
綁定非成員函數(shù)的時(shí)候俐芯,可以把調(diào)用者去掉就可以了:
int add1(int i, int j, int k) {
return i + j + k;
}
auto add2 = std::bind(add1, std::placeholders::_1, std::placeholders::_2, 10);
// 函數(shù)add2 = 綁定add1函數(shù)棵介,參數(shù)1不變,參數(shù)2不變吧史,參數(shù)3固定為10.
還有一個(gè)需要注意的地方就是參數(shù)占位符如果調(diào)換位置邮辽,在實(shí)際調(diào)用過程中,傳入?yún)?shù)也會調(diào)換位置贸营。這樣就比較靈活吨述,一個(gè)函數(shù)通過bind的時(shí)候調(diào)換參數(shù)的位置,設(shè)置可以實(shí)現(xiàn)函數(shù)重載的功能钞脂。
5.然后接上面的看一下lambda表達(dá)式設(shè)置回調(diào)
auto func = [](std::string str) {
CCLOG("==========lambda=======%s", str.c_str());
};
myClass.setCallBack(func);
這個(gè)就比較簡單了揣云,具體lambda的用法,以后用到了再深究吧
lambda表達(dá)式基本用法
1)聲明Lambda表達(dá)式
Lambda表達(dá)式完整的聲明格式如下:
[capture list] (params list) mutable exception-> return type { function body }
各項(xiàng)具體含義如下
- capture list:捕獲外部變量列表
- params list:形參列表
- mutable指示符:用來說用是否可以修改捕獲的變量
- exception:異常設(shè)定
- return type:返回類型
- function body:函數(shù)體
2)具體用法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> myvec{ 3, 2, 5, 7, 3, 2 };
sort(myvec.begin(), myvec.end(), [](int a, int b) -> bool { return a < b; }); // Lambda表達(dá)式
cout << "lambda expression:" << endl;
for (int it : myvec)
cout << it << ' ';
}
3)捕獲外部變量
[]:默認(rèn)不捕獲任何變量冰啃;
[=]:默認(rèn)以值捕獲所有變量邓夕;
[&]:默認(rèn)以引用捕獲所有變量刘莹;
[x]:僅以值捕獲x,其它變量不捕獲焚刚;
[&x]:僅以引用捕獲x点弯,其它變量不捕獲;
[=, &x]:默認(rèn)以值捕獲所有變量矿咕,但是x是例外抢肛,通過引用捕獲;
[&, x]:默認(rèn)以引用捕獲所有變量碳柱,但是x是例外雌团,通過值捕獲;
[this]:通過引用捕獲當(dāng)前對象(其實(shí)是復(fù)制指針)士聪;
[*this]:通過傳值方式捕獲當(dāng)前對象;