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

设计需求:

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

开发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 notifycation
bool 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)();


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值