C++的成员函数指针与Cococs2d-x的selector机制

在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>

// 定义一个函数指针类型, MethodPointer
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;
}
在文件的上面我们定义了一个函数指针类型MethodPointer,和它对应的函数类型应该是没有返回值的,且有一个Int参数的函数, 例如上文中的void printNum(int num)函数, 在main中我们定义了一个MethodPointer指针,指向了printNum方法,然后执行mp(444);就相当于执行了printNum(444)方法。 

C++的成员函数指针与Cococs2d-x的selector机制


对于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;
}


执行结果为 
C++的成员函数指针与Cococs2d-x的selector机制

可见, 在click方法中我们执行了doSth方法, 打印出了888这几个数字。


参考资料  :  http://zh.wikipedia.org/wiki/%E7%B1%BB%E6%88%90%E5%91%98%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88 



最后看看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;
}

输出结果 

C++的成员函数指针与Cococs2d-x的selector机制


C++的成员函数指针与Cococs2d-x的selector机制,布布扣,bubuko.com

C++的成员函数指针与Cococs2d-x的selector机制

上一篇:ASP.NET Aries 入门开发教程4:查询区的下拉配置


下一篇:《语义网基础教程(原书第3版)》—— 1.3 一种分层方法