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

C/C++ bind函数应用详解 文章目录知识前导头文件bind介绍bind函数:bind简述:placeholders用法探究单个参数多个参数成员函数 知识前导 头文件 #include <functional> bind介绍 bind函数: 使用规则: auto newCallable = bind(callable, arg_list); bind简述: bind函数看做一个通用的函数适配器,它接受一个可调用对象callable,生成一个新的可调用对象newCallable。 它可以把原可调用对象callable的某些 阅读详情

引用:http://blog.youkuaiyun.com/star530/article/details/21245565

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

首先看一段代码:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //先是创建3个精灵  
  2. boy = Sprite::create("boy.png");//创建boy  
  3. boy->setPosition(Point(visibleSize.width/2,visibleSize.height/2));  
  4. this->addChild(boy,1);  
  5.   
  6. girl_1 = Sprite::create("girl_1.png");//创建girl1  
  7. girl_1->setPosition(Point(visibleSize.width/3,visibleSize.height/2));  
  8. girl_1->setTag(10);  
  9. this->addChild(girl_1,1);  
  10.   
  11. girl_2 = Sprite::create("girl_3.png");//创建girl2  
  12. girl_2->setPosition(Point(2*visibleSize.width/3,visibleSize.height/2));  
  13. girl_2->setTag(20);  
  14. this->addChild(girl_2,1);  
  15.   
  16. //让boy运动,通过Callfunc回调到callback1  
  17. boy->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,100)),  
  18.                                     CallFunc::create(CC_CALLBACK_0(HelloWorld::callback1,this)),  
  19.                                     NULL));  
三个回调函数的实现:

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void HelloWorld::callback1()  
  2. {  
  3.     CCLOG("in callback1");  
  4.     //girl1运动,最后回调到callback2  
  5.     girl_1->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,150)),  
  6.                                             CallFunc::create(CC_CALLBACK_0(HelloWorld::callback2,this,girl_1)),  
  7.                                             NULL));  
  8. }  
  9. void HelloWorld::callback2(Node* sender)  
  10. {  
  11.     //girl2运动,最后回调到callback3  
  12.     girl_2->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,200)),  
  13.         CallFunc::create(CC_CALLBACK_0(HelloWorld::callback3,this,girl_2,99)),  
  14.         NULL));  
  15.   
  16.     CCLOG("in callback2,sender tag is:%d",(Sprite*)sender->getTag());  
  17. }  
  18. void HelloWorld::callback3(Node* sender, long data)  
  19. {  
  20.     //最终输出  
  21.     CCLOG("in callback3,everything is OK,sender tag is:%d,date is:%ld",(Sprite*)sender->getTag(),data);  
  22.     CCLOG("girl2 dandan ask:what fake the CC_CALLBACK is?");  
  23. }  

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


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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // new callbacks based on C++11  
  2. #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)  
  3. #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)  
  4. #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)  
  5. #define CC_CALLBACK_3(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, 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,如下,

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int callback(int one,char two,double three);  
下面我们用bind来调用callback

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. auto newCallback = bind(callback,_1,_2,1.5);  
  2. int x = newCallback(10,'h');  //这句相当于:int x = callback(10,'h',1.5);  
“_1″是一个占位符对象,用于表示当函数callback通过函数newCallback进行调用时,函数newCallback的第一个参数在函数callback的参数列表中的位置。第一个参数称为”_1″, 第二个参数为”_2″,依此类推,有意思吧。至于‘1.5’是指默认参数,它处于_1和_2的后面,所以它就是double类型的参数了.
在强调一点就是:_1这类占位符都定义在一个名为placeholders的命名空间中,而这个命名空间本身定义在std的命名空间中。为了使用这些名字,两个命名空间都要写上,
如:

std::placeholders::_1;

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

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

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //让boy运动,通过Callfunc回调到callback1  
  2. boy->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,100)),  
  3.                                     CallFunc::create(std::bind(&HelloWorld::callback1,this)),  
  4.                                     NULL));  
[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void HelloWorld::callback1()  
  2. {  
  3.     CCLOG("in callback1");  
  4.     //girl1运动,最后回调到callback2  
  5.     girl_1->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,150)),  
  6.                                             CallFunc::create(std::bind(&HelloWorld::callback2,this,girl_1)),  
  7.                                             NULL));  
  8.     CCLOG("boy ask girl_1:can you do my girlFriends?");  
  9. }  
  10. void HelloWorld::callback2(Node* sender)  
  11. {  
  12.     //girl2运动,最后回调到callback3  
  13.     girl_2->runAction(CCSequence::create(MoveBy::create(1.0f,Point(0,200)),  
  14.         CallFunc::create(std::bind(&HelloWorld::callback3,this,girl_1,99)),  
  15.         NULL));  
  16.   
  17.     CCLOG("in callback2,sender tag is:%d",(Sprite*)sender->getTag());  
  18.     CCLOG("girl_1 ask girl_2:I love girl_2");  
  19. }  
  20. void HelloWorld::callback3(Node* sender, long data)  
  21. {  
  22.     //最终输出  
  23.     CCLOG("in callback3,everything is OK,sender tag is:%d,date is:%ld",(Sprite*)sender->getTag(),data);  
  24.     CCLOG("girl2 dandan say:I know how to use CC_CALLBACK!");  
  25. }     


恩,就是这样子了。bind与CC_CALLBACK之间的关系就是这么的...简单。
金融机构和贷款产品数据抓取:使用Python爬虫技术获取金融机构的贷款产品信息与条件 本文介绍了如何使用Python爬虫技术抓取金融机构的贷款产品信息,包括静态网页抓取和动态网页抓取两种方法。通过requestsSelenium等工具,我们能够轻松抓取银行和消费金融平台上的贷款信息,并存储和分析数据。随着技术的发展,我们还可以扩展爬虫功能,抓取更多的金融机构网站,或者结合自然语言处理技术对贷款产品的评论进行情感分析,为用户提供更多维度的贷款决策支持。 阅读详情

相关推荐

【亲测可用!】阿里达摩院开源实时数字人对话VideoChat本地部署教程(8G显存可跑)

本文主要记录在部署阿里达摩院开源实时数字人对话VideoChat时遇到的问题,希望对各位技术开发或爱好者有所帮助!

波点兔的博客 3898

std::function与std::bind的使用总结

文章转载自: C++中函数指针的用途非常广泛,例如回调函数,接口类的设计等,但函数指针始终不太灵活,它只能指向全局或静态函数,对于类成员函数、lambda表达式或其他可调用对象就无能为力了,因此,C++11推出了std::function与std::bind这两件大杀器。 std::function vs 函数指针 C++函数指针相信大家用的很多了,用法最广泛的应该就是先定义函数指针的类型,然后在声明一个函数指针的变量作为另一个函数的入参,以此作为回调函数,如下列代码所示: typedef voi

zhc的博客 3857

实战分享:如何用YOLOv5s+BIFPN高效检测隧道裂缝(附数据集获取)

本文详细介绍了如何利用YOLOv5s结合BIFPN(双向特征金字塔网络)构建高效的隧道裂缝智能检测系统。文章从高质量数据集构建、针对性数据增强、模型架构选型与调优,到工程化部署全链路进行了实战分享,旨在为基础设施自动化巡检提供兼顾精度与速度的解决方案。

weixin_29062823的博客 380

函数对象包装器(std::function、std::bind / std::placeholder)

这部分内容虽然属于标准库的一部分,但是从本质上来看,它却增强了 C++ 语言运行时的能力,这部分内容也相当重要,所以放到这里来进行介绍。 std :: function和std :: bind的主要用途之一是安全函数指针。网上有很多文章解释了函数指针在C / C ++中是如何有用的。例如,它们对于实现回调机制很有用。也就是说,你有一些功能需要很长时间才能执行,但你不想等待它返回然后你可以在单独的...

Jeff_的博客 837

stm32h743的hrtim使用生成pwm波

HRTIM(High-Resolution Timer)是一种高精度定时器,其时钟频率可直接与CPU主频同步,达到480MHz。相比之下,其他传统定时器需挂载在APB总线上,受总线频率限制,最高仅支持240MHz。这种直接时钟同步机制显著提升了定时器的分辨率和精度。

d13211322的博客 1614

用LTspice仿真Buck电路输出电容:从参数计算到波形优化的全流程演示

本文详细介绍了使用LTspice仿真Buck电路输出电容的全流程,从理论计算到波形优化。通过解析关键参数如纹波电压、瞬态响应和ESR,结合工程计算方法和LTspice仿真技巧,帮助工程师优化Buck电路设计,解决输出纹波过大和瞬态响应不佳的问题。

night的博客 852

C++:std::function和std::bind实现跨文件回调函数

  文件结构如下:两个类(A,B) 分别对应h和cpp(A.h A.cpp B.h B.cpp),A中定义两个函数funcA和funcB, B中定义funcC。funcA调用funcC,funcC调用funcB。funcC调用funcB使用回调函数思路,在funcA调用funcC时就传入funcB的函数指针。test.cpp是外界调用。具体的源代码如下: A.h #ifndef A_H #define A_H #include<iostream> #include<functional&g

gls_nuaa的博客 692

基于YOLOv5/v8/v10的垃圾分类识别系统:设计实现与性能优化(附代码+数据集)

做完这个毕设,你已经掌握了从数据准备、模型训练到界面开发的全流程。把模型部署到树莓派上,做个真正的“智能垃圾桶”硬件装置;加入语音提示功能,检测到垃圾后自动语音播报类别;试试融合多个YOLO模型的优势,让分类精度再上一个台阶。按照这个教程一步步做,你的毕设不仅能顺利完成,还能做出很多亮点。要是过程中遇到啥问题,别慌,慢慢琢磨或者咱们一起聊聊,肯定能把这个毕设做成让你满意的作品。

know_F0727的博客 463

C/C++回调函数使用和参数绑定std::bind函数的使用

最近在使用一个C语言库函数的时候,遇到一个问题: 该库函数有些函数设置了回调函数, 我构造了C++类, 想用其成员函数作为回调函数的参数赋值, 因为类方法有一个隐含参数this指针,无法直接作为回调使用,就想到了使用bind方法进行函参适配。结果证明是不可行的。 查阅了很多资料, 得 出 结 论 \color{red}{得出结论} 得出结论: C语言的函数指针无法进行 C++ std::bind函数适配。😞 只用C++的std::function<函数类型>才能进行std::bind函数适配。

ss49344的博客 3865

【uniapp踩坑记】App Store上传失败:Invalid Swift Support错误怎么解决?

作为一个前端出身的开发者,用 uniapp 开发原生 App 已经够挑战了,打包 iOS 上传 App Store 更是处处暗雷。这次的坑虽然小,但确实容易忽略。如果你也遇到了类似的报错,希望这篇文章能帮你少踩一次坑!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1143

芒果YOLO11改进145:Loss损失函数KLD:即插即用 NeurIPS顶会论文,独家首发原创新颖|通过 Kullback-Leibler 散度学习用于目标检测的高精度边界框

旋转检测Loss损失函数KLD:即插即用 NeurIPS顶会论文,独家首发原创新颖|通过 Kullback-Leibler 散度学习用于目标检测的高精度边界框

包括YOLOv5、YOLOv7、YOLOv8等模型改进 566

C++中的回调函数再次总结(std::bind和function)

回调函数的再一次整理。

记录一些平时工作或者学习中的瞬间 2298

【QNX+Android虚拟化方案】129 - USB眼图参数配置

【QNX+Android虚拟化方案】129 - USB眼图参数配置

|~~~热爱生活、努力学习的小伙汁~~~| 821

CC_CALLBACK 与 std::bind之间不可告人的秘密

转载自  Cocos2dx 3.0 过渡篇(十七) std::bind与CC_CALLBACK不得不说的故事 本篇的主题就是揭露CC_CALLBACK 与 std::bind之间不可告人的秘密...... 首先看一段代码: [cpp] view plaincopy //先是创建3个精灵   boy = Sprite::creat

llll523181260的专栏 688

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

cocos2dx 3.2 回调

回调

sssssNian的专栏 609

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

std::bind

可以方便地用来创建回调函数,尤其是在那些需要用户提供一个在未来某个时间点执行,并且可能带有预定义参数的函数的地方。,以及预先设定的参数。这样就创建了一个可以作为回调函数使用的对象。函数,它接受一个无参数的回调函数,并在一个指定的延迟后执行。函数,从而实现了在2秒后通过回调机制调用。在这个例子中,我们首先定义了一个类。

qq_44186550的博客 628

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【c++11】std::bind使用

1.绑定全局函数 [ #include <iostream> #include <functional> typedef std::function<void(int, int)> callback; void fun(int n1, int n2) { OutputDebugString(L"fun"); } 使用: std::function<void(int, int)> ss1 = std::bind(fun, std::placeho...

kevin的博客 341

c++之function和bind详解-SurfaceFlinger学习必备语法基础

function是一个通用的函数对象容器,可以存储任意可调用对象(函数、函数指针、成员函数、成员变量、lambda表达式,任何function对象,比如一个类,定义了operator()),并提供了一致的接口来调用这些对象。通过function,可以将一个函数或函数对象作为参数传递给其他函数或存储在容器中,大大提高了灵活性。参数解释:Ret:代表调用function的返回结果的类型Args:代表是参数的类型。demo展示:1、function存储函数指针方式return a*2;

learnframework的博客 1522

Cocos2dx-3.0--- std::bind与CC_CALLBACK不得不说的故事

本篇的主题就是揭露CC_CALLBACK 与 std::bind之间不可告人的秘密...... 首先看一段代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //先是创建3个精

u012861978的专栏 936

Chromium bind和callback库泛化仿函数解析

从 Chromium Bind函数分析泛化仿函数

qq_45663002的博客 817

宏CC_CALLBACK_1

CC_CALLBACK_1宏是将函数与对象绑定在一起,1表示这个函数有一个参数。 li'ru

爱生活,爱编程 873

CC_CALLBACK原理及应用

c++ 11 基础 :     std::function         类模版 std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标进行存储、复制、和调用操作,这些目标包括函数、lambda表达式、绑定表达式、以及其它函数对象等。 用法示例: ①保存自由函数 ? 1 2 3 4 5 6 7

yaonai2003的专栏 928

cocos2dx的CC_CALLBACK是个什么宏

coco2dx看了段时间了,但是期初对于CC_CALLBACK这个宏只会用不理解是什么意思,今天一探究竟。 先来看源码CC_CALLBACK_1的定义,其他的一次类推。 #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__V

麻花 896
上一篇: Python中optparse模块使用浅析
下一篇: cocos2dx3.0rc导出自定义类到lua的方法详细步骤
CekineLin
博客等级 码龄15年 1粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值