从cocos2dx中寻找函数指针传递的方法
目的
看到群里有个朋友搞了好几天函数指针传递,没搞好。所以写一篇文章,旨在从cocos2dx中帮朋友们找到如何传递指针。
旧版本的函数指针传递
全局函数函数指针调用
一般在C++11之前,我们一般是这样定义一个函数指针类型。
- typede void(*pFunc)(int,...);
什么意思呢?
- typedef void/*return type of function*/
- (*pFunc/*the pointer of function*/)
- (int,.../*the types of function parameters*/);
- typedef void/*函数返回类型*/(*pFunc/*函数指针*/)(int,.../*函数参数类型*/);
OK,那么好了,该如何调用呢?
一般来说是像下面这样的。
- typedef void(*pFunc)();
- void fA(){ };
- void fB(pFunc pf){ (*pf)(/*里面加函数参数*/) };
- void fC(){ fB(&fA);};
即为在fC中调用fB,fB的参数为fA指针。
成员函数函数指针的调用
那么成员函数如何调用呢?
只需要加一个类名修饰符即可。
示例如下:
- class C;
- typedef void(C::*pFunc)();
- void C::fA(){};
- void C::fB(pFunc pf){ (this->*pf)()};
- void C::fC(){this->fB(&C::fA);};
其实,有心的朋友应该会注意到cocos2dx 版本中的各种selector即为宏定义的函数指针的引用,定义如下:
- typedef void (Ref::*SEL_CallFunc)();
- typedef void (Ref::*SEL_CallFuncN)(Node*);
- typedef void (Ref::*SEL_CallFuncND)(Node*, void*);
- typedef void (Ref::*SEL_CallFuncO)(Ref*);
- typedef void (Ref::*SEL_MenuHandler)(Ref*);
- typedef void (Ref::*SEL_SCHEDULE)(float);
- #define callfunc_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFunc>(&_SELECTOR)
- #define callfuncN_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncN>(&_SELECTOR)
- #define callfuncND_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncND>(&_SELECTOR)
- #define callfuncO_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncO>(&_SELECTOR)
- #define menu_selector(_SELECTOR) static_cast<cocos2d::SEL_MenuHandler>(&_SELECTOR)
- #define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)
所以不懂函数指针的朋友完全可以模仿它。 相信你很快就能上手。
C++11 中std::function的应用
cocos2dx 里面std::function定义的各种回调的解析
假设我们不知道std::function如何使用,那么只有浏览cocos2dx3.X里面的源码,我们会发现有大量的callBack 是用std::function定义的。
我们在此,首先用cocos2dx里面的网络http请求的返回函数举例。
HttpRequest 的回调定义为
inline void setResponseCallback(const ccHttpRequestCallback& callback)
{
_pCallback = callback;
}
追踪ccHttpRequestCallback,可以发现ccHttpRequestCallback即为std::function定义的:
typedef std::function<void(HttpClient* client, HttpResponse* response)> ccHttpRequestCallback;
使用过的同学应该知道怎么调用的,
一般都是 setResponseCallback(CC_CALLBACK_2(ClassName::jsonRequestCompleted,this));
CC_CALLBACK是什么东东,其实就是std::bind的引用宏定义。我们查看定义如下:
- #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__)
很明显,CC_CALLBACK_2就是 std::bind里面传参数,第一个是引用参数表示函数,第二个是目标,第三个,第四个是占位符,后面是不定参数。
所以可以等价代换为std::bind,那么我们上面的回调可以变成
setResponseCallback(std::bind(&ClassName::jsonRequestCompleted,this,std::placeholders::_1,std::placeholders::_2));
自定义std::function的应用
通过以上分析,相信大家已经掌握了如何通过std::function传递函数,以及std::bind去调用。不过为了照顾一些基础薄弱的朋友,我还是给出一个简单的例子。
- class C;
- void C::fA(){}
- void C::fB(const std::function<void()> &func)
- {
- if (func)
- {
- func();
- }
- }
- void C::fC()
- {
- fB(std::bind(&c::fA,this));
- }
关于非成员函数使用std::function
非成员函数使用std::function和上面的函数指针实际上是一致的,鉴于它比较容易,就不在此赘述了,还不会的朋友可以试一下。
申明:
本文原创,转载请注明出处。http://blog.csdn.net/q229827701/article/details/41479753
从cocos2dx中寻找函数指针传递的方法的更多相关文章
- 1、C语言中的函数指针
一 通常的函数调用 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) { MyFun ...
- Keil C51 中的函数指针和再入函数
函数指针是C语言中几个难点之一.由于8051的C编译器的独特要求,函数指针和再入函数有更多的挑战需要克服.主要由于函数变量的传递.典型的(绝大部分8051芯片)函数变量通过堆栈的入栈和出栈命令来传递. ...
- QT中使用函数指针
想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...
- Delphi中的函数指针判断是否为空
delphi函数指针 只有@@p才代表了函数指针本身的地址 assigned(p) 判断是否为空 或者用 @p=nil 来判断函数指针是不是为空 Delphi中的函数指针实际上就是指针,只是在使用 ...
- C++中使用函数指针 【瓦特芯笔记】
在C++类中使用函数指针. 类型定义: typedef 返回类型(类名::*新类型)(参数表) //类定义 class CA { public: char lcFun(int a) ...
- C语言结构体中的函数指针
这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in ...
- C 中typedef 函数指针的使用
类型定义的语法可以归结为一句话:只要在变量定义前面加上typedef,就成了类型定义.这儿的原本应该是变量的东西,就成为了类型. int integer; //整型变量int *pointer ...
- C++中的函数指针和指针函数
C++中的函数指针和指针函数 数组名一般可以被当成指向数组第一个元素的常量指针,同样的情况,在函数中,函数名可以本当成指向函数的常量指针,假如一个函数已经定义,那么它在计算机中一定有特定的 ...
- C语言中的函数指针
C语言中的函数指针 函数指针的概念: 函数指针是一个指向位于代码段的函数代码的指针. 函数指针的使用: #include<stdio.h> typedef struct (*fun_t ...
随机推荐
- Linux功能-环境变量
linux系统中有很多重要的环境变量,我们可以用env命令查看它们. 变量是由固定的“变量名”与用户或系统设置的“变量值”两部分组成,也可以自行修改. [root@localhost ~]# env ...
- java cache过期策略两种实现,一个基于list轮询一个基于timer定时
最近项目要引入缓存机制,但是不想引入分布式的缓存框架,所以自己就写了一个轻量级的缓存实现,有两个版本,一个是通过timer实现其超时过期处理,另外一个是通过list轮询. 首先要了解下ja ...
- UITableView的使用及性能优化
UITableView可谓是日常开发中最重要的控件之一,而使用UITableView最重要的在于性能优化.iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万个UITa ...
- 第一次做的struts2与spring整合
参考:http://www.cnblogs.com/S-E-P/archive/2012/01/18/2325253.html 这篇文章说的关键就是“除了导入Struts2和Spring的核心库之外, ...
- java nio的基本原理
buffer<->channel->selector--handler... buffer与channel双通道传输数据,selector中可以有多个channel,这个样就可以多个 ...
- 利用SOLR搭建企业搜索平台 之——配置文件
运行solr是个很简单的事,如何让solr高效运行你的项目,这个就不容易了.要考虑的因素太多.这里很重要一个就是对solr的配置要了解.懂得配置文件每个配置项的含义,这样操作起来就会如鱼得水! 在so ...
- MyEclipse 10离线安装PyDev插件
PyDev for Eclipse, 经过测试,一般在线安装会失败(不能访问某些网站所致) 以下为离线安装步骤 1 下载 PyDev 2.8.2, 链接:http://sourceforge.net ...
- 配置Tomcat 中文字符集问题
找到Tomcat安装路径下的conf文件夹下的server.xml配置文件,修改配置Tomcat端口的标签"Connector",添加URIEncoding属性,代码如下: < ...
- laravel/laravel和laravel/framework有何区别?
在安装laravel的时候,我们一般是download github上的laravel/laravel,随后执行composer install,在这个过程中,你会发现composer其中的一项工作是 ...
- 设置sudo不输入密码 sudoers 编辑出错后的补救方法
一 设置sudo为不需要密码 有时候我们只需要执行一条root权限的命令也要su到root,是不是有些不方便?这时可以用sudo代替.默认新建的用户不在sudo组,需要编辑/etc/sudoers文件 ...
