原文:http://blog.csdn.net/u013368288/article/details/24659773
首先看一段代码:
- //先是创建3个精灵
- boy=Sprite::create("boy.png");//创建boy
- boy->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
- this->addChild(boy,1);
- girl_1=Sprite::create("girl_1.png");//创建girl1
- girl_1->setPosition(Point(visibleSize.width/3,visibleSize.height/2));
- girl_1->setTag(10);
- this->addChild(girl_1,1);
- girl_2=Sprite::create("girl_3.png");//创建girl2
- girl_2->setPosition(Point(2*visibleSize.width/3,visibleSize.height/2));
- girl_2->setTag(20);
- this->addChild(girl_2,1);
- //让boy运动,通过Callfunc回调到callback1
- boy->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,100)),
- CallFunc::create(CC_CALLBACK_0(HelloWorld::callback1,this)),
- NULL));
- voidHelloWorld::callback1()
- {
- CCLOG("incallback1");
- //girl1运动,最后回调到callback2
- girl_1->runAction(CCSequence::create(MoveBy::create(1.0f,150)),
- CallFunc::create(CC_CALLBACK_0(HelloWorld::callback2,this,girl_1)),
- NULL));
- }
- voidHelloWorld::callback2(Node*sender)
- {
- //girl2运动,最后回调到callback3
- girl_2->runAction(CCSequence::create(MoveBy::create(1.0f,200)),
- CallFunc::create(CC_CALLBACK_0(HelloWorld::callback3,girl_2,99)),
- NULL));
- CCLOG("incallback2,sendertagis:%d",(Sprite*)sender->getTag());
- }
- voidHelloWorld::callback3(Node*sender,longdata)
- {
- //最终输出
- CCLOG("incallback3,everythingisOK,sendertagis:%d,dateis:%ld",(Sprite*)sender->getTag(),data);
- CCLOG("girl2dandanask:whatfaketheCC_CALLBACKis?");
- }
整个过程就是boy“勾引”girl1,但girl1显然对异性兴趣不大,于是她也勾引girl2......可是,girl2对同性异性都没兴趣,她只是淡淡的说了句:CC_CALLBACK到底是什么?,调试如图:
好吧,先让我回口血,然后再来回答girl2的问题:CC_CALLBACK到底是什么碗糕(东东)?
我们先进CC_CALLBACK源码里看看:
- //newcallbacksbasedonC++11
- #defineCC_CALLBACK_0(__selector__,__target__,...)std::bind(&__selector__,##__VA_ARGS__)
- #defineCC_CALLBACK_1(__selector__,std::placeholders::_1,##__VA_ARGS__)
- #defineCC_CALLBACK_2(__selector__,std::placeholders::_2,##__VA_ARGS__)
- #defineCC_CALLBACK_3(__selector__,std::placeholders::_3##__VA_ARGS__)
这里主要注意两点:一是 std::bind,二是##_VA_ARGS_; ##_VA_ARGS_是可变参数宏,我就不多说了。 重点讲的是std::bind。
std::bind是在C++ 11里新加入的成员。可以将bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表.
调用bind的一般形式为:
auto newCallback = bind(callback,arg_list);
其中,newCallback是一个可调用对象,arg_list是可以用逗号分隔的参数列表,至于是啥参数,那就看callback函数里有啥参数啦。也就是说,当我们调用newCallback时,newCallback会调用函数callback,并传递参数arg_list给callback.
看完上面的内容你的理解可能还比较模糊,那直接来个例子:有一个函数callback,如下,
- intcallback(intone,chartwo,doublethree);
- autonewCallback=bind(callback,_1,_2,1.5);
- intx=newCallback(10,'h');//这句相当于:intx=callback(10,'h',1.5);
在强调一点就是:_1这类占位符都定义在一个名为placeholders的命名空间中,而这个命名空间本身定义在std的命名空间中。为了使用这些名字,两个命名空间都要写上,如:
std::placeholders::_1;
这样编写贼麻烦,所以在要使用_1时,可以加上这么一句:
using namespace namespace_name; 恩,ok
恩,bind就介绍到这,讲的比较浅,不理解的可以百度研究下。最后再回过头来看下CC_CALLBACK的定义,是不是清晰多了?
最后在举个例子吧,还是之前的boy,girl1,girl2,只是他们之间传递“爱意”的方式要换下了。不用CC_CALLBACK,改用std::bind。代码如下 :
- //让boy运动,通过Callfunc回调到callback1
- boy->runAction(CCSequence::create(MoveBy::create(1.0f,
- CallFunc::create(std::bind(&HelloWorld::callback1,
- NULL));
- voidHelloWorld::callback1()
- {
- CCLOG("incallback1");
- //girl1运动,最后回调到callback2
- girl_1->runAction(CCSequence::create(MoveBy::create(1.0f,
- CallFunc::create(std::bind(&HelloWorld::callback2,
- NULL));
- CCLOG("boyaskgirl_1:canyoudomygirlFriends?");
- }
- voidHelloWorld::callback2(Node*sender)
- {
- //girl2运动,最后回调到callback3
- girl_2->runAction(CCSequence::create(MoveBy::create(1.0f,
- CallFunc::create(std::bind(&HelloWorld::callback3,girl_1,
- NULL));
- CCLOG("incallback2,(Sprite*)sender->getTag());
- CCLOG("girl_1askgirl_2:Ilovegirl_2");
- }
- voidHelloWorld::callback3(Node*sender,data);
- CCLOG("girl2dandansay:IknowhowtouseCC_CALLBACK!");
- }