cocos2dx中的吧。 menu_selector看成是函数名,_SELECTOR就是函数的参数,也就是说把_SELECTOR这个参数强制转换成SEL_MenuHandler,而SEL_MenuHandler的定义为
typedef void (CCObject::*SEL_MenuHandler)(CCObject*); 也就是符合这样的格式的函数指针。
类似的。如果我们定义 typedef void (CCNode::*SEL_MyHandler)(int); 然后写一个
#define my_selector(_SELECTOR) (SEL_MyHandler)(&_SELECTOR)
只要我们在继承自CCNode(因为我们这里typedef void (CCNode)用的是CCNode)的类中定义一个参数为int返回值为void的函数,比如 void MyClass::myfunc(int); MyClass继承自CCNode,那么我们就可以这样用 my_selector(MyClass::myfunc)
//A.h
typedef void (CCNode::*SEL_MyHandler)(int);
#define my_selector(_SELECTOR) (SEL_MyHandler)(&_SELECTOR)
class MyClass : public CCNode //继承自CCNode
{
public:
void myfunc(int val){ CCLog("%d",val)}; //按照自己定义的格式写函数
void callback { //某个函数例子
B b;
b.registercallback(my_selector(MyClass::myfunc), this); //注册回调函数,其实就是赋值,用法跟menu_selector一样的
b.execute(); //看看是怎么执行的
}
};
//B.h
#include "A.h"
class B
{
public:
void execute() ;
void registercallback(SEL_MyHandler, CCNode* ptarget); //只是赋值而已
private:
CCNode* target;
SEL_MyHandler handler;
};
//B.cpp
void execute()
{
(target->*handler)(124123); //这里是关键,通过target去调用注册的函数,参数自己设
}
void registercallback(SEL_MyHandler myhander, CCNode* ptarget)
{
handler = myhanler; target = ptarget;
}
这句话翻译过来就是说:
首先,menu_selector()是一个函数,_SELECTOR是menu_selector()这个函数的参数;
其次,SEL_MenuHandler也是一个函数,&_SELECTOR是这个函数的参数;
最后,menu_selector(_SELECTOR)其实就是SEL_MenuHandler(&_SELECTOR)的代号,程序代码中只要出现menu_selector(_SELECTOR)的地方,都会被编译器自动替换为SEL_MenuHandler(&_SELECTOR)。
注意, menu_selector(_SELECTOR)是一个整体,SEL_MenuHandler(&_SELECTOR)也是一个整体,两部分之间要有空格才不至于产生歧义。而且,SEL_MenuHandler外面的括号也是为避免发生歧义而设置的。
宏函数定义。
宏,就是替换模式,注意替换在编译之前。
调用:menu_selector(1)
在编译之前被替换为:
SEL_MenuHandler(1_SELECTOR)
圆括号是为了防止歧义和“粘连”的界定符号,没有特殊意义。
地址符 是替换符的一种