目的

看到群里有个朋友搞了好几天函数指针传递,没搞好。所以写一篇文章,旨在从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. OpenCV4Android开发之旅

    http://blog.csdn.net/yanzi1225627/article/details/16917961

  2. USACO Section 3.3: Home on the Range

    到最后发现是DP题 /* ID: yingzho1 LANG: C++ TASK: range */ #include <iostream> #include <fstream> ...

  3. IO(二)

    package com.bjsxt.io.buffered; import java.io.BufferedInputStream; import java.io.BufferedOutputStre ...

  4. BZOJ 2956 模积和

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2956 题意:给出n和m.计算: 思路: i64 n,m; i64 cal(i64 m,i ...

  5. What is the difference between DAO and DAL?

    What is the difference between DAO and DAL? The Data Access Layer (DAL) is the layer of a system tha ...

  6. Evaluate Reverse Polish Notation(堆栈)

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

  7. JavaScript高级程序设计之数据类型

    首先讲讲关于js文件放置的问题,如果把<script>放在head标签处,浏览器会先加载完该处的所有不使用defer属性的js文件再呈现页面的内容(浏览器在遇到body标签时才呈现内容), ...

  8. 纠结和郁闷的存在感-关于DirectX与HLSL的矩阵存储方式---转载好文章

    我常常这么大胆的认为,搞科学的人总是喜欢用各种让常人难以理解的复杂方式去处理某些其实可能很简单的事情,这种情况在他自身擅长的.有着诸多对手竞争的领域上极为常见.比如吧,搞DirectX的人用了左手坐标 ...

  9. CSS 中浮动的使用

    float none 正常显示 left 左浮动 right 右浮动 clear none 允许两边浮动 left 不允许左边浮动 right 不允许右边浮动 both 不允许两边浮动 <!DO ...

  10. git plumbing 更加底层命令解析-深入理解GIT

    原文: http://rypress.com/tutorials/git/plumbing 本文详细介绍GIT Plumbing--更加底层的git命令,你将会对git在内部是如何管理和呈现一个项目r ...