在Cocos2d-x中点击某个按钮要执行一个回调函数时,一般的写法是以下这样 :
- // add a "share" icon to exit the progress. it's an autorelease object
- CCMenuItemImage *pShareItem = CCMenuItemImage::create(
- "share.png",
- "share.png",
- this,
- menu_selector(HelloWorld::menuShareCallback));
其中的HelloWorld::menuShareCallback是HelloWorld类的一个函数, 生命为 :
- // a selector callback to share button
- void menuShareCallback(CCObject* pSender);
这个menuShareCallback就相当与Java中Listener的回调函数, 那么Cocos2d-x的selector机制是如何实现的呢 ?
要明白selector机制, 我们首先要清楚C/C++语言中的函数指针, 函数指针其实就是指向函数的指针。 在C/C++中, 函数会以内存地址来标识, 从函数的内存地址开始执行就相当于执行该函数。那么用什么来代表函数指针的地址呢, 其实C/C++语言中的函数名就代表了函数在内存中的地址。看下面的例子 :
- #include <iostream>
- // 定义一个函数指针类型, <span style="font-family: Arial, Helvetica, sans-serif;">MethodPointer</span>
- typedef void (*MethodPointer)(int num);
- // 普通函数
- void printNum(int num)
- {
- cout << "The num is : " <<num<<endl;
- }
- int main(int argc, const char * argv[])
- {
- MethodPointer mp = printNum;
- mp(444);
- return 0;
- }
对于C++来说还有一种是成员函数指针,它与C中的函数指针类似, 只是指针指向的是某个类中的成员函数。看下面这个例子 :
头文件
- #ifndef __MenberCallback__MemberPointer__
- #define __MenberCallback__MemberPointer__
- class MemberPointer;
- // 定义一个成员函数指针
- typedef void (MemberPointer::*MCallback)(int num);
- #include <iostream>
- class MemberPointer
- {
- public:
- MemberPointer();
- ~MemberPointer();
- void click(MCallback callback);
- void doSth(int code);
- } ;
- #endif /* defined(__MenberCallback__MemberPointer__) */
cpp
- #include <iostream>
- #include "MemberPointer.h"
- using namespace std;
- MemberPointer::MemberPointer()
- {
- }
- MemberPointer::~MemberPointer()
- {
- }
- void MemberPointer::doSth(int code)
- {
- cout<<"call back method. "<<code<<endl;
- }
- void MemberPointer::click(MCallback callback)
- {
- // 执行回调, 因为在callback中传递的是自身的回调函数doStn,所以直接用this
- (this->*callback)(888);
- }
main函数 :
- int main(int argc, const char * argv[])
- {
- MemberPointer *mPointer = new MemberPointer();
- mPointer->click(&MemberPointer::doSth) ;
- return 0;
- }
可见, 在click方法中我们执行了doSth方法, 打印出了888这几个数字。
参考资料 : 成员函数指针
最后模拟一下Cocos2d-x中按钮的selector的实现, 就直接上代码了。
CCObject.h
- <span style="font-size:14px;">//
- // CCObject.h
- // membercallback
- //
- // Created by mrsimple on 4/1/14.
- // Copyright (c) 2014 mrsimple. All rights reserved.
- //
- #ifndef __membercallback__CCObject__
- #define __membercallback__CCObject__
- #include <iostream>
- class CCObject
- {
- public:
- CCObject();
- virtual ~CCObject();
- } ;
- // 定义回调函数为CCObject或者CCObject子类中的成员函数,两个参数
- typedef void (CCObject::*ButtonCallback)(CCObject* pSender, int stCode);
- // 定义selector
- #define button_selector(_SELECTOR) (ButtonCallback)(&_SELECTOR)
- #endif /* defined(__membercallback__CCObject__) */</span><span style="font-size:18px;">
- </span>
- #include "CCObject.h"
- CCObject::CCObject()
- {
- }
- CCObject::~CCObject()
- {
- }
CCButton.h
- //
- // CCButton.h
- // membercallback
- //
- // Created by mrsimple on 4/1/14.
- // Copyright (c) 2014 mrsimple. All rights reserved.
- //
- #ifndef __membercallback__CCButton__
- #define __membercallback__CCButton__
- #include <iostream>
- #include "CCObject.h"
- class CCButton : public CCObject
- {
- public:
- CCButton();
- virtual ~CCButton();
- void click(CCObject* pSender);
- void setCallback(ButtonCallback callback );
- private:
- void buttonClick(CCObject* pSender, int code) ;
- ButtonCallback _buttonCallback;
- CCObject* mSender;
- } ;
- #endif /* defined(__membercallback__CCButton__) */
CCButton.cpp
- //
- // CCButton.cpp
- // membercallback
- //
- // Created by mrsimple on 4/1/14.
- // Copyright (c) 2014 mrsimple. All rights reserved.
- //
- #include "CCButton.h"
- using namespace std;
- CCButton::CCButton()
- :mSender(NULL)
- {
- }
- CCButton::~CCButton()
- {
- delete mSender;
- }
- // 设置回调函数
- void CCButton::setCallback(ButtonCallback callback)
- {
- _buttonCallback = callback ;
- }
- // 按钮点击操作, 执行回调
- void CCButton::click(CCObject* pSender)
- {
- mSender = pSender ;
- // 执行回调函数,这里执行的则是CCScene中的buttonCallback函数
- (mSender->*_buttonCallback)(mSender, 123);
- }
CCScene.h
- //
- // CCScene.h
- // membercallback
- //
- // Created by mrsimple on 4/1/14.
- // Copyright (c) 2014 mrsimple. All rights reserved.
- //
- #ifndef __membercallback__CCScene__
- #define __membercallback__CCScene__
- #include <iostream>
- #include <iostream>
- #include "CCObject.h"
- #include "CCButton.h"
- class CCScene : public CCObject
- {
- public:
- CCScene();
- virtual ~CCScene();
- void clickButton();
- private:
- CCButton* mButton;
- void buttonCallback(CCObject* pSender, int code);
- };
- #endif /* defined(__membercallback__CCScene__) */
CCScene.cpp
- //
- // CCScene.cpp
- // membercallback
- //
- // Created by mrsimple on 4/1/14.
- // Copyright (c) 2014 mrsimple. All rights reserved.
- //
- #include "CCObject.h"
- #include "CCButton.h"
- #include "CCScene.h"
- using namespace std;
- // 构造函数, 创建CCButton
- CCScene::CCScene()
- :mButton(new CCButton())
- {
- // 设置回调函数
- mButton->setCallback( button_selector(CCScene::buttonCallback) ) ;
- }
- CCScene::~CCScene()
- {
- delete mButton ;
- }
- // 模拟点击按钮的操作
- void CCScene::clickButton()
- {
- if ( mButton != NULL )
- {
- // 按钮点击
- mButton->click(this) ;
- }
- }
- // 点击按钮, 回调该函数
- void CCScene::buttonCallback(CCObject *pSender, int code)
- {
- cout<<"In CCScene --> callback, code = "<<code<<endl;
- }
main.cpp 使用示例 :
- //
- // main.cpp
- // membercallback
- //
- // Created by mrsimple on 4/1/14.
- // Copyright (c) 2014 mrsimple. All rights reserved.
- //
- #include <iostream>
- #include "CCObject.h"
- #include "CCScene.h"
- int main(int argc, const char * argv[])
- {
- CCScene* sc = new CCScene();
- sc->clickButton() ;
- return 0;
- }
输出结果
最后看看Cocos2d-x中的selector的实现, 直接上代码测试:
头文件
//
// MemberPointer.h
// MenberCallback
//
// Created by mrsimple on 3/13/14.
// Copyright (c) 2014 mrsimple. All rights reserved.
//
#ifndef __MenberCallback__MemberPointer__
#define __MenberCallback__MemberPointer__
#include <iostream>
class MemberPointer;
// 定义一个成员函数指针
typedef void (MemberPointer::*MCallback)(int num);
// 定义selector
#define callback_selector(_SEL) (MCallback)(&_SEL)
class MemberPointer
{
public:
MemberPointer();
~MemberPointer();
void click(MCallback callback);
void doSth(int code);
void doSelector(int code);
} ;
#endif /* defined(__MenberCallback__MemberPointer__) */
cpp
//
// MemberPointer.cpp
// MenberCallback
//
// Created by mrsimple on 3/13/14.
// Copyright (c) 2014 mrsimple. All rights reserved.
//
#include <iostream>
#include "MemberPointer.h"
using namespace std;
MemberPointer::MemberPointer()
{
}
MemberPointer::~MemberPointer()
{
}
void MemberPointer::doSelector(int code)
{
cout<<"doSelector "<<code<<endl;
}
void MemberPointer::doSth(int code)
{
cout<<"call back method. "<<code<<endl;
}
void MemberPointer::click(MCallback callback)
{
// 执行回调, 因为在callback中传递的是自身的回调函数doStn,所以直接用this
(this->*callback)(888);
}
main
//
// main.cpp
// MenberCallback
//
// Created by mrsimple on 3/13/14.
// Copyright (c) 2014 mrsimple. All rights reserved.
//
#include <iostream>
#include "Selector.h"
#include "MemberPointer.h"
typedef void (*MP)(int stCode);
void printNum(int num)
{
cout << "The num is : " <<num<<endl;
}
int main(int argc, const char * argv[])
{
MemberPointer *mPointer = new MemberPointer();
mPointer->click(&MemberPointer::doSth) ;
// selector的使用, 注意这里和上面的区别, callback_selector (XXXXXXXX)
mPointer->click(callback_selector(MemberPointer::doSelector)) ;
return 0;
}
输出结果
转载:http://blog.csdn.net/bboyfeiyu/article/details/21181503