目的

看到群里有个朋友搞了好几天函数指针传递,没搞好。所以写一篇文章,旨在从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. jquery 计算输入的文本的utf-8字节长度

    jquery-2.1.1.min.js /*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license ...

  2. python 捕获 shell/bash 脚本的输出结果

    #!/usr/bin/python## get subprocess module import subprocess ## call date command ##p = subprocess.Po ...

  3. leetcode Database3

    一.Rank Scores Write a SQL query to rank scores. If there is a tie between two scores, both should ha ...

  4. 观察者模式最佳案例实现[JAVA][原创]

    /** * American Stock Exchange market(ASE) has a list of stocks.A stock object has two perspective in ...

  5. AWS 之Load Balance篇

    public class CreateELB { /// <summary> /// 连接AWS服务器 /// </summary> /// <param name=&q ...

  6. linux 2.6up的设备和设备驱动模型

    在linux2.6 的设备和设备驱动模型构架中,所有的外部设备和驱动程序都挂在总线上 ,总线分为(usb   -- USB设备,PCI  -- PCI 设备 platform --   直接和处理器进 ...

  7. Trianglify – 五彩缤纷的 SVG 背景图案

    Trianglify 是一个能够生成五颜六色的三角形图案的 JavaScript 库,可以用来作为 SVG 图像和 CSS 背景.它的灵感来自于 Btmills 的 Geopattern,并使用 d3 ...

  8. UVa 11481 (计数) Arrange the Numbers

    居然没有往错排公式那去想,真是太弱了. 先在前m个数中挑出k个位置不变的数,有C(m, k)种方案,然后枚举后面n-m个位置不变的数的个数i,剩下的n-k-i个数就是错排了. 所以这里要递推一个组合数 ...

  9. (六)6.7 Neurons Networks whitening

    PCA的过程结束后,还有一个与之相关的预处理步骤,白化(whitening) 对于输入数据之间有很强的相关性,所以用于训练数据是有很大冗余的,白化的作用就是降低输入数据的冗余,通过白化可以达到(1)降 ...

  10. 【英语】Bingo口语笔记(30) - 表示“拒绝”