目的

看到群里有个朋友搞了好几天函数指针传递,没搞好。所以写一篇文章,旨在从cocos2dx中帮朋友们找到如何传递指针。

旧版本的函数指针传递

全局函数函数指针调用

一般在C++11之前,我们一般是这样定义一个函数指针类型。

  1. typede void(*pFunc)(int,...);

什么意思呢?

  1. typedef  void/*return type of function*/
  1. (*pFunc/*the pointer of function*/)
  1. (int,.../*the types of function parameters*/);
  2. typedef  void/*函数返回类型*/(*pFunc/*函数指针*/)(int,.../*函数参数类型*/);

OK,那么好了,该如何调用呢?

一般来说是像下面这样的。

  1. typedef void(*pFunc)();
  2. void fA(){ };
  3. void fB(pFunc pf){ (*pf)(/*里面加函数参数*/) };
  4. void fC(){  fB(&fA);};

即为在fC中调用fB,fB的参数为fA指针。

成员函数函数指针的调用

那么成员函数如何调用呢?

只需要加一个类名修饰符即可。

示例如下:

  1. class C;
  2. typedef void(C::*pFunc)();
  3. void C::fA(){};
  4. void C::fB(pFunc pf){ (this->*pf)()};
  5. void C::fC(){this->fB(&C::fA);};

其实,有心的朋友应该会注意到cocos2dx 版本中的各种selector即为宏定义的函数指针的引用,定义如下:

  1. typedef void (Ref::*SEL_CallFunc)();
  2. typedef void (Ref::*SEL_CallFuncN)(Node*);
  3. typedef void (Ref::*SEL_CallFuncND)(Node*, void*);
  4. typedef void (Ref::*SEL_CallFuncO)(Ref*);
  5. typedef void (Ref::*SEL_MenuHandler)(Ref*);
  6. typedef void (Ref::*SEL_SCHEDULE)(float);
  7. #define callfunc_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFunc>(&_SELECTOR)
  8. #define callfuncN_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncN>(&_SELECTOR)
  9. #define callfuncND_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncND>(&_SELECTOR)
  10. #define callfuncO_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncO>(&_SELECTOR)
  11. #define menu_selector(_SELECTOR) static_cast<cocos2d::SEL_MenuHandler>(&_SELECTOR)
  12. #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的引用宏定义。我们查看定义如下:

  1. #define CC_CALLBACK_0(__selector__,__target__, ...) std::bind(&__selector__,__target__, ##__VA_ARGS__)
  2. #define CC_CALLBACK_1(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, ##__VA_ARGS__)
  3. #define CC_CALLBACK_2(__selector__,__target__, ...) std::bind(&__selector__,__target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
  4. #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去调用。不过为了照顾一些基础薄弱的朋友,我还是给出一个简单的例子。

  1. class C;
  2. void C::fA(){}
  3. void C::fB(const std::function<void()> &func)
  4. {
  5. if (func)
  6. {
  7. func();
  8. }
  9. }
  10. void C::fC()
  11. {
  12. fB(std::bind(&c::fA,this));
  13. }

关于非成员函数使用std::function

非成员函数使用std::function和上面的函数指针实际上是一致的,鉴于它比较容易,就不在此赘述了,还不会的朋友可以试一下。

申明:

本文原创,转载请注明出处。http://blog.csdn.net/q229827701/article/details/41479753

从cocos2dx中寻找函数指针传递的方法的更多相关文章

  1. 1、C语言中的函数指针

    一 通常的函数调用 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) { MyFun ...

  2. Keil C51 中的函数指针和再入函数

    函数指针是C语言中几个难点之一.由于8051的C编译器的独特要求,函数指针和再入函数有更多的挑战需要克服.主要由于函数变量的传递.典型的(绝大部分8051芯片)函数变量通过堆栈的入栈和出栈命令来传递. ...

  3. QT中使用函数指针

    想仿命令行,所以定义了一个类,让一个String 对应一个 function,将两者输入list容器. 类中定义了 QString commandStr; void (MainWindow::*com ...

  4. Delphi中的函数指针判断是否为空

    delphi函数指针 只有@@p才代表了函数指针本身的地址   assigned(p) 判断是否为空 或者用 @p=nil 来判断函数指针是不是为空 Delphi中的函数指针实际上就是指针,只是在使用 ...

  5. C++中使用函数指针 【瓦特芯笔记】

         在C++类中使用函数指针. 类型定义:      typedef 返回类型(类名::*新类型)(参数表) //类定义 class CA { public: char lcFun(int a) ...

  6. C语言结构体中的函数指针

      这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in ...

  7. C 中typedef 函数指针的使用

    类型定义的语法可以归结为一句话:只要在变量定义前面加上typedef,就成了类型定义.这儿的原本应该是变量的东西,就成为了类型. int integer;     //整型变量int *pointer ...

  8. C++中的函数指针和指针函数

    C++中的函数指针和指针函数       数组名一般可以被当成指向数组第一个元素的常量指针,同样的情况,在函数中,函数名可以本当成指向函数的常量指针,假如一个函数已经定义,那么它在计算机中一定有特定的 ...

  9. C语言中的函数指针

    C语言中的函数指针 函数指针的概念:   函数指针是一个指向位于代码段的函数代码的指针. 函数指针的使用: #include<stdio.h> typedef struct (*fun_t ...

随机推荐

  1. 《mysql悲观锁总结和实践》-悲观锁

    最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持 ...

  2. 路径名称和struts.xml配置不一致导致struts2报404

    struts.xml中写的是<result name="...">authorityInterceptor/xxx.jsp</result> 但是实际的文件 ...

  3. FFmpeg FFmpeg的使用及常用参数

    FFmpeg的使用及常用参数 一.下载: 官网:http://ffmpeg.org/ 二.demo: 1 class Program 2 { 3 static void Main(string[] a ...

  4. R语言学习笔记——Base Graphics

    做exploratory data annalysis的作业,差点被虐死了,R从头开始,边做边学,最后搞到一点多才弄完,还有一个图怎么画都不对,最后发现是数据读取的时候有问题. 用来画图的数据来自:h ...

  5. Eclipse插件安装与使用 —— Properties Editor

    一.下载     首先当然是下载插件啦! 下载地址:http://sourceforge.jp/projects/propedit/downloads/40156/jp.gr.java_conf.us ...

  6. django中post方法和get方法的不同

    当我们提交表单仅仅需要获取数据时就可以用GET: 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST. 在这个搜索书籍的例子里,我们 ...

  7. 《c程序设计语言》读书笔记-字符型0-9转为数字0-9

    #include <stdio.h> #define Num 10 int atoi(char s[]); int main() { int c,i = 0; char s[Num]; i ...

  8. $ is not defined错误类型

    <script src='js/jtouch/jquery.js'></script> <script type="text/javascript"& ...

  9. hdu1828(线段树+扫描线)

    又知道了线段树的一种用法,除了单点更新,区间更新,还有这种在一段线段上标号但不往下推. 真是神奇 hdu1828 #include <iostream> #include <stdi ...

  10. 51nod1406 与查询

    这题卡I/O...dp一下... #include<cstdio> #include<cstring> #include<cctype> #include<a ...