Cocos2dx 3.0 过渡篇(十七) std::bind与CC_CALLBACK不得不说的故事

Cocos2dx 3.0 过渡篇(十七) std::bind与CC_CALLBACK不得不说的故事,第1张

概述本篇的主题就是揭露CC_CALLBACK 与 std::bind之间不可告人的秘密...... 首先看一段代码: [cpp] view plain copy //先是创建3个精灵   boy = Sprite::create("boy.png");//创建boy   boy->setPosition(Point(visibleSize.width/2,visibleSize.height/2));

本篇的主题就是揭露CC_CALLBACK 与 std::bind之间不可告人的秘密......

首先看一段代码:

[cpp] view plain copy //先是创建3个精灵@H_301_20@@H_301_20@@H_301_20@ @H_301_25@boy=Sprite::create("boy.png"@H_301_20@);@H_301_20@//创建boy@H_301_20@@H_301_20@@H_301_20@ boy->setposition(Point(visibleSize.wIDth/2,visibleSize.height/2));@H_301_20@ @H_301_25@this@H_301_20@->addChild(boy,1);@H_301_20@@H_301_20@ @H_301_20@ @H_301_25@girl_1=Sprite::create("girl_1.png"@H_301_20@);@H_301_20@//创建girl1@H_301_20@@H_301_20@@H_301_20@ girl_1->setposition(Point(visibleSize.wIDth/3,visibleSize.height/2));@H_301_20@ @H_301_25@girl_1->setTag(10);@H_301_20@ this@H_301_20@->addChild(girl_1,1);@H_301_20@@H_301_20@ @H_301_25@@H_301_20@ girl_2=Sprite::create("girl_3.png"@H_301_20@);@H_301_20@//创建girl2@H_301_20@@H_301_20@@H_301_20@ @H_301_25@girl_2->setposition(Point(2*visibleSize.wIDth/3,visibleSize.height/2));@H_301_20@ girl_2->setTag(20);@H_301_20@ @H_301_25@this@H_301_20@->addChild(girl_2,1);@H_301_20@@H_301_20@ @H_301_20@ @H_301_25@//让boy运动,通过Callfunc回调到callback1@H_301_20@@H_301_20@@H_301_20@ boy->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,100)),@H_301_20@ @H_301_25@CallFunc::create(CC_CALLBACK_0(HelloWorld::callback1,this@H_301_20@)),@H_301_20@@H_301_20@ NulL));@H_301_20@ 三个回调函数的实现: [cpp] view plain copy voID@H_301_20@HelloWorld::callback1()@H_301_20@@H_301_20@ @H_301_25@{@H_301_20@ cclOG("incallback1"@H_301_20@);@H_301_20@@H_301_20@ @H_301_25@//girl1运动,最后回调到callback2@H_301_20@@H_301_20@@H_301_20@ girl_1->runAction(CCSequence::create(MoveBy::create(1.0f,150)),@H_301_20@ @H_301_25@CallFunc::create(CC_CALLBACK_0(HelloWorld::callback2,this@H_301_20@,girl_1)),@H_301_20@@H_301_20@ NulL));@H_301_20@ @H_301_25@}@H_301_20@ voID@H_301_20@HelloWorld::callback2(Node*sender)@H_301_20@@H_301_20@ @H_301_25@{@H_301_20@ //girl2运动,最后回调到callback3@H_301_20@@H_301_20@@H_301_20@ @H_301_25@girl_2->runAction(CCSequence::create(MoveBy::create(1.0f,200)),@H_301_20@ CallFunc::create(CC_CALLBACK_0(HelloWorld::callback3,girl_2,99)),@H_301_20@@H_301_20@ @H_301_25@NulL));@H_301_20@ @H_301_20@ @H_301_25@cclOG("incallback2,sendertagis:%d"@H_301_20@,(Sprite*)sender->getTag());@H_301_20@@H_301_20@ }@H_301_20@ @H_301_25@voID@H_301_20@HelloWorld::callback3(Node*sender,@H_301_20@long@H_301_20@data)@H_301_20@@H_301_20@ {@H_301_20@ @H_301_25@//最终输出@H_301_20@@H_301_20@@H_301_20@ cclOG("incallback3,everythingisOK,sendertagis:%d,dateis:%ld"@H_301_20@,(Sprite*)sender->getTag(),data);@H_301_20@@H_301_20@ @H_301_25@cclOG("girl2dandanask:whatfaketheCC_CALLBACKis?"@H_301_20@);@H_301_20@@H_301_20@ }@H_301_20@

整个过程就是boy“勾引”girl1,但girl1显然对异性兴趣不大,于是她也勾引girl2......可是,girl2对同性异性都没兴趣,她只是淡淡的说了句:CC_CALLBACK到底是什么?@H_301_20@,调试如图:


好吧,先让我回口血,然后再来回答girl2的问题:CC_CALLBACK到底是什么碗糕(东东)?
我们先进CC_CALLBACK源码里看看:

[cpp] view plain copy //newcallbacksbasedonC++11@H_301_20@@H_301_20@@H_301_20@ @H_301_25@#defineCC_CALLBACK_0(__selector__,__target__,...)std::bind(&__selector__,##__VA_ARGS__)@H_301_20@@H_301_20@@H_301_20@ #defineCC_CALLBACK_1(__selector__,std::placeholders::_1,##__VA_ARGS__)@H_301_20@@H_301_20@@H_301_20@ @H_301_25@#defineCC_CALLBACK_2(__selector__,std::placeholders::_2,##__VA_ARGS__)@H_301_20@@H_301_20@@H_301_20@ #defineCC_CALLBACK_3(__selector__,std::placeholders::_3##__VA_ARGS__)@H_301_20@@H_301_20@@H_301_20@ 看完后恍然大悟!不看不知道,一看...和没看一样...@H_301_20@
这里主要注意两点:一是 std::bind@H_301_20@,二是##_VA_ARGS_@H_301_20@; ##_VA_ARGS_是可变参数宏,我就不多说了。 重点讲的是std::bind。
std::bind是在C++ 11里新加入的成员。可以将bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表.
调用bind的一般形式为:
@H_301_20@auto newCallback = bind(callback,arg_List);@H_301_20@
其中,newCallback是一个可调用对象,arg_List是可以用逗号分隔的参数列表,至于是啥参数,那就看callback函数里有啥参数啦。也就是说,当我们调用newCallback时,newCallback会调用函数callback,并传递参数arg_List给callback.
看完上面的内容你的理解可能还比较模糊,那直接来个例子:有一个函数callback,如下, [cpp] view plain copy int@H_301_20@callback(@H_301_20@int@H_301_20@one,@H_301_20@char@H_301_20@two,@H_301_20@double@H_301_20@three);@H_301_20@@H_301_20@ 下面我们用bind来调用callback [cpp] view plain copy autonewCallback=bind(callback,_1,_2,1.5);@H_301_20@@H_301_20@ @H_301_25@int@H_301_20@x=newCallback(10,@H_301_20@'h'@H_301_20@);@H_301_20@//这句相当于:intx=callback(10,'h',1.5);@H_301_20@@H_301_20@@H_301_20@ “_1″是一个占位符对象,用于表示当函数callback通过函数newCallback进行调用时,函数newCallback的第一个参数在函数callback的参数列表中的位置。第一个参数称为”_1″,第二个参数为”_2″,依此类推,有意思吧。至于‘1.5’是指默认参数,它处于_1和_2的后面,所以它就是double类型的参数了.
在强调一点就是:_1这类占位符都定义在一个名为placeholders@H_301_20@的命名空间中,而这个命名空间本身定义在std的命名空间中。为了使用这些名字,两个命名空间都要写上,如:

std::placeholders::_1@H_301_20@;@H_301_20@

这样编写贼麻烦,所以在要使用_1时,可以加上这么一句:
using namespace namespace_name@H_301_20@;@H_301_20@ 恩,ok

恩,bind就介绍到这,讲的比较浅,不理解的可以百度研究下。最后再回过头来看下CC_CALLBACK的定义,是不是清晰多了?
最后在举个例子吧,还是之前的boy,girl1,girl2,只是他们之间传递“爱意”的方式要换下了。不用CC_CALLBACK,改用std::bind。代码如下 :

[cpp] view plain copy //让boy运动,通过Callfunc回调到callback1@H_301_20@@H_301_20@@H_301_20@ @H_301_25@boy->runAction(CCSequence::create(MoveBy::create(1.0f,@H_301_20@ CallFunc::create(std::bind(&HelloWorld::callback1,@H_301_20@@H_301_20@ @H_301_25@NulL));@H_301_20@ [cpp] view plain copy voID@H_301_20@HelloWorld::callback1()@H_301_20@@H_301_20@ @H_301_25@{@H_301_20@ cclOG("incallback1"@H_301_20@);@H_301_20@@H_301_20@ @H_301_25@//girl1运动,最后回调到callback2@H_301_20@@H_301_20@@H_301_20@ girl_1->runAction(CCSequence::create(MoveBy::create(1.0f,@H_301_20@ @H_301_25@CallFunc::create(std::bind(&HelloWorld::callback2,@H_301_20@@H_301_20@ NulL));@H_301_20@ @H_301_25@cclOG("boyaskgirl_1:canyoudomygirlFrIEnds?"@H_301_20@);@H_301_20@@H_301_20@ }@H_301_20@ @H_301_25@voID@H_301_20@HelloWorld::callback2(Node*sender)@H_301_20@@H_301_20@ {@H_301_20@ @H_301_25@//girl2运动,最后回调到callback3@H_301_20@@H_301_20@@H_301_20@ girl_2->runAction(CCSequence::create(MoveBy::create(1.0f,@H_301_20@ @H_301_25@CallFunc::create(std::bind(&HelloWorld::callback3,girl_1,@H_301_20@@H_301_20@ NulL));@H_301_20@ @H_301_25@@H_301_20@ cclOG("incallback2,(Sprite*)sender->getTag());@H_301_20@@H_301_20@ @H_301_25@cclOG("girl_1askgirl_2:Ilovegirl_2"@H_301_20@);@H_301_20@@H_301_20@ }@H_301_20@ @H_301_25@voID@H_301_20@HelloWorld::callback3(Node*sender,data);@H_301_20@@H_301_20@ @H_301_25@cclOG("girl2dandansay:IkNowhowtouseCC_CALLBACK!"@H_301_20@);@H_301_20@@H_301_20@ }@H_301_20@ 恩,就是这样子了。bind与CC_CALLBACK之间的关系就是这么的...简单。 总结

以上是内存溢出为你收集整理的Cocos2dx 3.0 过渡篇(十七) std::bind与CC_CALLBACK不得不说故事全部内容,希望文章能够帮你解决Cocos2dx 3.0 过渡篇(十七) std::bind与CC_CALLBACK不得不说的故事所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1009753.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存