(一)C++ 11 std::bind 与原来的bind1st 2nd 有什么区别?
C++98中,有两个函数bind1st和bind2nd,它们分别可以用来绑定functor的第 一个和第二个参数,它们都是只可以绑定一个参数。各种限制,使得bind1st和bind2nd的可用性大大降低。
图中可以看到C++14更强大
std::bind就是废止了bind1st和bind2nd这二个函数配接器(effective C++ 40条)里这么翻译,一共有四个标准配接器(bind1st,bind2nd not1,not2)说实在这四个研究过半天,也用过,感觉就是半成品,好在C++11废了他们。
关于std::bind 看了不少资料,下面这位总结很好,有深度有例子,就不细说了,里面几点重要话我在下面提出来。
http://blog.csdn.net/elloop/article/details/50323113
【C++ STL学习与应用总结】22: 函数组合之1:如何使用std::bind (since C++11)
1:bind是函数组合概念
std::bind是STL实现函数组合概念的重要手段,std::bind可以绑定
普通函数(函数指针)、
lambda表达式、
成员函数、
成员变量、
模板函数、
嵌套std::bind等
2:bind返回值
bind返回一个基于fn的函数对象(function object), 其参数被绑定到args上.
fn的参数要么是绑定到值,要么是绑定到placeholders(占位符,如_1, _2, …, _N)
3:以下是使用std::bind的一些需要注意的地方:
-
bind预先绑定的参数需要传具体的变量或值进去,对于预先绑定的参数,是pass-by-value的;
-
对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的;
-
bind的返回值是可调用实体,可以直接赋给std::function对象;
-
对于绑定的指针、引用类型的参数,使用者需要保证在可调用实体调用之前,这些参数是可用的;
-
类的this可以通过对象或者指针来绑定。
4: std::bind 绑定类成员函数、成员变量
成员函数区别于普通函数的一个特殊之处在于,其第一个参数必须是该类型的一个对象(或对象的指针或引用),
如果成员函数有多个参数,参数是从bind的第二个参数开始,
std::bind(&成员函数,第一个参数,第二个参数,第三个参数..)
<<理解CC_CALLBACK_0, CC_CALLBACK_1, CC_CALLBACK_2, CC_CALLBACK_3>>
作者同上:elloophttp://blog.csdn.net/elloop/article/details/50445722
cocos2d中有这样的定义
-
#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__)
(二) coscos2d 3.x 中的std::bind案例代码
CC_CALLBACK__1 _2 _3 代表成员函数参数个数
-
点击(此处)折叠或打开
-
bool RedSide::init()
-
{
-
...
-
EventListenerCustom*listener=EventListenerCustom::create("robot_attacking",CC_CALLBACK_1(RedSide::attackedByGreen,this));
-
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(listener,1);
-
...
-
}
-
-
void RedSide::attackedByGreen(cocos2d::EventCustom*event)
-
{
-
......
-
}
CC_CALLBACK_1 绑定成员 RedSide::attackedByGreen,用了
一个占位符来锁定此函数需要一个参数
Create 函数定义
-
点击(此处)折叠或打开
-
EventListenerCustom*EventListenerCustom::create(conststd::string&eventName,conststd::function&callback)
-
{
-
EventListenerCustom*ret=new(std::nothrow)EventListenerCustom();
-
if(ret&&ret->init(eventName,callback))
-
{
-
ret->autorelease();
-
}
-
else
-
{
-
CC_SAFE_DELETE(ret);
-
-
}
-
return ret;
-
}
事件的触发
-
点击(此处)折叠或打开
-
EventCustom event("robot_attacking");
-
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event);
最终通过"robot_attacking"EventDispatcher 会找到此事件的listener,然后listener里保存着回调functor, functor 会被传递一个event参数,
进行回调就回到了成员函数这里。
-----------------------------------------------------------------------------------------------------------------------
Cocos2d 3.x 里有多种事件类型,每一种事件类型对就一种事件监听器,事件监听器保存着不同的回调函数。
-
点击(此处)折叠或打开
-
auto listener=EventListenerTouchOneByOne::create();//创建一个单点触摸事件:EventListenerTouchAllAtOnce 为多点
-
auto listener1=EventListenerTouchOneByOne::create();
-
//设置这些事件的的回调方法
-
listener->onTouchBegan=CC_CALLBACK_2(HelloWorld::onTouchBegan,this);
-
bool HelloWorld::onTouchBegan(Touch*touch,Event*event)
-
{
-
}
阅读(4989) | 评论(0) | 转发(0) |