cocos2d-x中函数回调 事件监听机制详细解析 涉及c++成员函数指针

来源:互联网 发布:面向切面编程aop实现 编辑:程序博客网 时间:2024/05/13 06:52

 在做c++开发,尤其是游戏开发中,会经常遇到函数回调,及按钮事件监听,本质上他们用的都是函数指针,但是c++的成员函数指针和c语言的函数指针有一些不同。

比如一般外部函数指针:void (*fpt) (int x)  就是一个指向"返回值为空,参数为整形的函数"的指针。

一个成员函数指针包括成员函数的返回类型,后随::操作符类名,指针名和函数的参数。

一个指向CCObject类的成员函数指针格式为:

void (CCObject::*pmf)(int x);

我们就cocos2d-x menu中被点击的事件传递机制来解释一下它的回调机制以及函数指针的使用

我们以一个实例说明

程序中有一个根类,所有的类都继承于它

形参为根类指针时,传入的实参可以是指向派生类的指针,通过动态绑定机制,编译器在运行的时候

确定应该调用哪个对象的方法。


#include <iostream>  #include <string>using namespace std;class CCObject{public:};/* *********************************************** *定义基类成员函数指针 *函数成员在本例子中其实没用的, ***********************************************/typedef void (CCObject::*SEL_MenuHandle)(string str);#define menu_selector(_SELECTOR) (SEL_MenuHandle)(&_SELECTOR)//派生类class Menu : public CCObject{public:~Menu();//为按钮添加 消息对象 及收到消息后的对象的执行方法//检测到系统的点击事件void addTargetAndSelector(CCObject *obj,SEL_MenuHandle sel);//回调的执行者CCObject *m_pListen;//回调函数指针SEL_MenuHandle m_pfnSelector;};void Menu::addTargetAndSelector(CCObject *obj,SEL_MenuHandle sel){m_pListen = obj;m_pfnSelector = sel;cout <<"按钮开启监听状态"<<endl;cout << "请输入一个数,1 代表按钮被点击"<<endl;int num;cin >>num;if(num ==1){cout << "Menu检测到按钮点击,发送消息给CCLayer层"<<endl;//方法回调,发送给消息层的 btnClick 方法(m_pListen->*m_pfnSelector)("自己添加方法");}}Menu::~Menu(){}class CCLayer : public CCObject{public:void menu();void btnClick(string message);};void CCLayer::menu(){cout << "CCLayer层添加按钮事件" <<endl;Menu *myMenu = new Menu;//menu对象开启检查模式等待用户按下按键myMenu->addTargetAndSelector(this,menu_selector(CCLayer::btnClick));}void CCLayer::btnClick(string message){cout << "CCLayer 收到按钮被点击的消息,执行点击以后的事情" <<endl;}int main(void){CCLayer *layer = new CCLayer;layer->menu();return 0;}

在CCLayer层添加一个菜单按钮,添加按钮事件,我们模仿了一下cocos2d-x 按钮监听机制,在手机上当我们

按下屏幕时候,系统会捕捉到,这是一个高优先级的中断,程序响应这个中断后,系统暂停当前线程上其他进程把消息发给menu对象,我们用等待用户输入的模式来模仿手机的按钮按下,当手机上按钮被 按下时,即用户输入1,此时,menu把这个消息发送给CCLayer游戏层,CCLayer层接收到这个事件后,会停止当前程序,跳转到btnClick()中,执行按钮被按下的动作,这样就完成了事件监听及函数回调。

#define menu_selector(_SELECTOR) (SEL_MenuHandle)(&_SELECTOR)


这个宏定义是对函数指针的强制类型转换,这是必须的,因为你传进来的函数名是 CCLayer::btnClick,是CCLayer类的成员函数, 而我们定义的时候是,void (CCObject::*mfp)(string str);  通过类型转换,以后只有是根类CCObject子类,都可以传进来,子类指针转为父类指针。

addTargetAndSelector(CCObject *obj,SEL_MenuHandle sel)

  CCLayer层 传的就是sel 就是 CCLayer::btnClick.

上面这些就是cocos2d-x 中按钮监听事件一些原理

我能讲的也不多,例子是做好的说明,大家有神马不明白可以仔细研究我写的这个Demo,如果有什么问题和想法,欢迎交流。。。。。

也可以发我邮箱,一起探讨。。。

thomashwak@gmail.com