[cocos2d-x]例如C++的成员函数指针实现委托、监听者模式

来源:互联网 发布:淘宝种子新规 编辑:程序博客网 时间:2024/05/23 21:49

设计需求:

游戏结束后,通知需要监听“游戏结束”消息的对象发送通知。

开发unity3d中我们知道c#有默认的delegate实现委托event的事件,很简单,前面的我的文章有做一个较为详细的介绍委托,以及此模式的一些优点。

送上传送门回忆下: http://blog.csdn.net/chiuan/article/details/7918833 


回归正题,我们直入正题,如何实现?

OK,可以google:“成员函数指针”相信大家会从中找到很多文章有涉及其介绍和使用。

1、先定义这个成员函数指针

typedef void (CCObject::*GAMEOVER_CALLBACK)();#define gameover_callback(_METHOD) (GAMEOVER_CALLBACK)(&_METHOD)

如上,定义一个是CCObject的返回void,传参为空的成员函数指针,命名为GAMEOVER_CALLBACK,因为指针是*,我们define一个宏处理,让输入的成员函数取其地址指针转化为函数指针。


2、定义引用成员函数指针的对象列表以及函数指针列表

CCArray* callbacksOfGameover;std::list<GAMEOVER_CALLBACK>* listOfGameover;

这里插一句补充,因为要调用这个成员函数方法,必须通过成员对象去调用。


3、实现监听者的3个方法,注册监听者、移除监听者、通知监听者

头文件定义:

bool registerObserverGameover(CCObject* obj,GAMEOVER_CALLBACK _method);bool removeObserverGameover(CCObject* obj);void notifyObserverGameover();

具体实现:

#pragma mark -#pragma mark delegate or notifycationbool GameLayer::registerObserverGameover(CCObject* obj,GAMEOVER_CALLBACK _method){    if (callbacksOfGameover && obj) {        callbacksOfGameover->addObject(obj);        //add method into vector.        listOfGameover->push_back(_method);        CCLOG("list of gameover size = %d",listOfGameover->size());    }    else CCLOG("register observer gameover error. maybe obj == null.");    return true;}bool GameLayer::removeObserverGameover(CCObject* obj){    if (callbacksOfGameover && obj && listOfGameover) {        int index = callbacksOfGameover->indexOfObject(obj);        callbacksOfGameover->removeObjectAtIndex(index);                std::list<GAMEOVER_CALLBACK>::iterator iterator = listOfGameover->begin();        for (int count = 0; iterator != listOfGameover->end(); iterator++) {            count+=1;            if (index + 1 == count) {                listOfGameover->erase(iterator);                break;            }            CCLOG("iterator position = %d",count);        }        CCLOG("list of gameover size = %d",listOfGameover->size());    }    else CCLOG("remove observer gameover error. maybe obj == null.");    return true;}void GameLayer::notifyObserverGameover(){    std::list<GAMEOVER_CALLBACK>::iterator iterator = listOfGameover->begin();    for (int i = 0 ; iterator != listOfGameover->end() ; iterator++) {        CCObject* obj = NULL;        if(i < callbacksOfGameover->count()){            obj = callbacksOfGameover->objectAtIndex(i);        }                if (obj) {            GAMEOVER_CALLBACK pCall = (GAMEOVER_CALLBACK)*iterator;            (obj->*pCall)();        }        i++;    }}

暂时还没发现cocos2d-x里面用什么来记录这个函数指针列表,用了list,其实也可以用vector。

然后注意一点就是如何调用对象的成员函数指针,就相当于调用这个方法一样!

GAMEOVER_CALLBACK pCall = (GAMEOVER_CALLBACK)*iterator;            (obj->*pCall)();

obj其实就是记录的某个对象,然后获取其成员函数指针pCall便可调用。其实这个很好理解,平时我们调用方法会是这样:

定义:void debug();

调用:debug();

那么把假如对象a里面的debug方法变成一个成员函数指针p调用:(a->*p)();