ocos2d-x--SEL_CallFuncN,SEL_CallFuncO等的区别

来源:互联网 发布:海岛大亨5mac版汉化 编辑:程序博客网 时间:2024/09/21 08:40

ocos2d-x中有大量的回调函数的应用,主要有以下几类,看下CCObject.h中的定义

typedef void (CCObject::*SEL_SCHEDULE)(float);// 用来调update
typedef void (CCObject::*SEL_CallFunc)();// 用来自定义无参回调
  1. typedef void (CCObject::*SEL_CallFuncN)(CCNode*);// 带执行者回调  
  2. typedef void (CCObject::*SEL_CallFuncND)(CCNode*, void*); // 带一个自定参数的回调  
  3. typedef void (CCObject::*SEL_CallFuncO)(CCObject*);  
  4. typedef void (CCObject::*SEL_MenuHandler)(CCObject*);  
  5. typedef void (CCObject::*SEL_EventHandler)(CCEvent*);  
  6. typedef int (CCObject::*SEL_Compare)(CCObject*);  
  7.   
  8. #define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)  
  9. #define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)  
  10. #define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)  
  11. #define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)  
  12. #define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)  
  13. #define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)  
  14. #define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)  
  15. #define compare_selector(_SELECTOR) (SEL_Compare)(&_SELECTOR)  
本质上,就是函数指针的应用。

但是,我们知道,在C中,函数指针是很普遍的应用。一般函数的函数名就是指针,不过是常量,再定义一个函数指针就是一个变量,这个变量可以指向这一类函数的地址。

比如:

  1. typedef void (*func)(int x);  
  2. void up(int s);  
  3. func f= up;  
  4. f(3);  

func是个函数指针类型:返回值是void,参数是一个int的函数。所以func的变量可以指向所有这一类的函数。
这是C风格的函数指针。但是在cocos2d-x中的回调,虽然还是函数指针,但已经有所区别。准确点说应该是成员函数指针。那么这普通的函数指针还可以来调成员函数吗?呵呵,如果能的话我就不用写这篇文章了。
C风格的函数指针要想调用成员函数,那么这个成员函数如果是static的也可以(为什么静态函数就可以,呵呵)。但是这样的话就会破坏类的结构。看cocos2d-x的实现也不是这样的。
这里说cocos2d-x的实现方式:
看上面的定义,如:typedef void (CCObject::*SEL_MenuHandler)(CCObject*);
看这个就应该大致可以知道它的实现了。
这个定义有点不一样,就是这个函数是CCObject的成员函数。这就是成员函数指针的定义。
大家知道,成员函数不能像普通C风格的函数那样调用,因为每个成员函数需要知道是哪个对象实例调用它的,隐含有一个this指针。这也解释了为什么静态函数可以用C风格的函数指针来回调,因为静态函数不需要对象实例就可以调用,呵呵。
既然定义成员函数指针,那么要用这个指针变量来调用回调函数,还需不需要对象实例呢。毫无疑问,还是需要的。
所以还必须有一个回调对象,CCObject *m_pListener。
这样调用: 

  1. (m_pListener->*m_pSelector)(CCObject *param);  
下面是我写的一个demo,类似cocos2d-x的实现:
  1. #ifndef __TestCallBack__Person__  
  2. #define __TestCallBack__Person__  
  3.   
  4. #include <iostream>  
  5. #include <string>  
  6.   
  7. using namespace std;  
  8.   
  9. // 基类  
  10. class Person {  
  11.   
  12. public:  
  13. void name(string name);  
  14. };  
  15.   
  16. // 定义基类的成员函数指针  
  17. typedef void (Person::*SEL_CallFun)(string str);  
  18.   
  19.   
  20. // 派生类  
  21. class Student : public Person{  
  22. private:  
  23. string m_name;  
  24. int m_age;  
  25.   
  26. public:  
  27. Student(string name, int age);  
  28. ~Student();  
  29.   
  30. // 回调  
  31. void callBack(string str);  
  32.   
  33. // say方法,要调用回调函数。  
  34. void say();  
  35. protected:  
  36. // 回调的执行者  
  37. Person *m_pListen;  
  38.   
  39. // 回调函数指针  
  40. SEL_CallFun m_pfnSelectior;  
  41. };  
实现:
  1. #include "Person.h"  
  2.   
  3. void Person::name(string name)  
  4. {  
  5. cout<<name<<endl;  
  6. }  
  7.   
  8. Student::Student(string name, int age)  
  9. {  
  10. this->m_name = name;  
  11. this->m_age = age;  
  12. }  
  13.   
  14. Student::~Student()  
  15. {  
  16.   
  17. }  
  18.   
  19. void Student::say()  
  20. {  
  21. cout<<"Hi this is a Student"<<endl;  
  22.   
  23. // 回调函数指针赋值。需要强转成 SEL_CallFun  
  24. m_pfnSelectior = (SEL_CallFun)(&Student::callBack);  
  25.   
  26. // 回调的执行对象,传this  
  27. m_pListen = this;  
  28.   
  29. // 调用回调,参数是个string  
  30. (m_pListen->*m_pfnSelectior)(m_name);  
  31. }  
  32.   
  33. // 成员函数,要回调的函数  
  34. void Student::callBack(string str)  
  35. {  
  36. cout<<"My name is "  
  37. << str<<endl  
  38. << "age is "  
  39. <<m_age<<endl;  
  40. }  
main
  1. #include <iostream>  
  2. #include "Person.h"  
  3.   
  4. int main(int argc, const char * argv[])  
  5. {  
  6.   
  7. Student *a = new Student("Join",20);  
  8. a->say();  
  9. return 0;  
  10. }  
输出:
  1. Hi this is a Student  
  2. My name is Join  
  3. age is 20  
如果再定义一个宏:
  1. #define callFunc_selector(_SELECTOR) (SEL_CallFun)(&_SELECTOR)  
那么调用就改成:
  1. m_pfnSelectior = callFunc_selector(Student::callBack);  

这个就是cocos2d-x的回调实现模式了。呵呵
仔细看看,是不是一样。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 离婚孩子落户口怎么办 父母离婚孩子出生证怎么办 离婚怎么办孩子的户口 离婚了儿子户口怎么办 性格不合离婚 孩子怎么办 前夫不迁走户口怎么办 我想离婚老婆不同意怎么办 要离婚没身份证怎么办 老婆怀孕想离婚怎么办 我老婆起诉离婚怎么办 父母冷战我该怎么办 经常跟父母亲吵架怎么办 14岁父母离婚怎么办 夫妻为钱吵架怎么办 离婚后担心孩子怎么办 不爱对方有孩子怎么办 爸和大伯吵架怎么办 孩子和家长吵架怎么办 老公吵架摔东西怎么办 楼上吵架摔东西怎么办 宿友没素质的人怎么办 父母人品差自私怎么办 家里穷压力大怎么办 偏执型人格障碍怎么办 遇到低素质保安怎么办 和老婆性格不合怎么办 当心理阴暗时怎么办 孩子胆子小怎么办呢? 父母伤亡的孩子怎么办 小孩上课老是走神怎么办 小孩上课老走神怎么办 小孩上课爱走神怎么办 孩子对学习成绩无所谓怎么办 孩子脾气特别倔强怎么办 没有规矩的孩子怎么办 孩子情商太低怎么办 4岁宝宝缺乏自信怎么办 孩子害羞不自信怎么办 说话脸红的人怎么办 胆小自卑不自信怎么办 孩子爱挑衣服怎么办