上一讲我们通过c#的代码理解了委托,这一讲我们就来说说在cocos2d-x中如何实现委托
cocos2d-x使用的是c/c++语言,c++中并没有委托的概念,但c++中有函数指针.利用函数指针我们就可以实现委托的机制
上代码:
.h文件:
#include "cocos2d.h" #include "B.h" using namespace cocos2d; //函数指针,定义了加法操作函数的形式 typedef int (B::*AddFunc)(int,int); class A { public: A(void); ~A(void); //执行加法操作 void excuteAdd(int a,int b,B *pTarget,AddFunc func); };
.cpp文件
#include "A.h" using namespace cocos2d; A::A(void){} A::~A(void){} void A::excuteAdd(int a,int b,B *pTarget,AddFunc func) { int z = (pTarget->*func)(a,b); CCLOG("result:%i",z); }
excuteAdd函数的内容我们可以看到这样的(pTarget->*func)(a,b)代码.这句代码表示执行pTarget对象中的AddFunc类型函数,并带入参数a,b.
获得pTarget与func后我们在此处对pTarget进行通知执行func,或者可以保存到类成员中在其他时刻对pTarget进行通知执行func.
我们再来看下B类的实现:
.h文件
#pragma once #include "cocos2d.h" using namespace cocos2d; class B { public: B(void); ~B(void); int Add(int a,int b); };.cpp文件
#include "B.h" using namespace cocos2d; B::B(void){} B::~B(void){} //加法操作 int B::Add(int a,int b) { return a+b; }B类很简单,实现了加法的具体操作.
最后我们再看一下,在main函数中如何使用的.
A *a = new A(); B *b = new B(); a->excuteAdd(2,3,b,(AddFunc)(&B::Add));实例化了A与B,执行a的的excuteAdd函数,参数a\b分别带入两个整数,pTarget带入b实例.func参数带入了B类的Add函数的地址,并把它强制转换为AddFunc函数指针类型.
func参数看起来是不是烦的很?按照cocos2dx中的习惯,我们定义个宏:
#define callAddFunc(_SELECTOR) (AddFunc)(&_SELECTOR).以callAddFunc(_SELECTOR)代替(AddFunc)(&_SELECTOR)
这样a->excuteAdd(2,3,b,(AddFunc)(&B::Add));就可以写成:
a->excuteAdd(2,3,b,callAddFunc(B::Add));这样就顺眼多了。
配合cocos2d-x系列笔记(9.1)---浅谈cocos2d-x使用函数指针实现委托(上)---通过c#代码理解委托该文章中对委托的定义,我们可以对代码做如下解释:
A接受到一个请求,要对某些事物进行处理,(这个请求是Main函数中对A的excuteAdd方法的调用)但A目前不知道该怎样处理这个事物,就把处理该事物的工作交给B以后去做.(A中并没有定义加法的具体操作方法)A会给B定义出一个函数的模板,指示B该去实现一个什么样的函数去处理这件事物.(A中定义了typedef int (B::*AddFunc)(int,int);告诉B加法要用这种形式的函数去处理)事物的处理由B全权负责,(在B中我们定义了Add函数进行了加法操作)而A只负责适时通知B什么时候该处理此事物.(A在excuteAdd中调用了(pTarget->*func)(a,b)通知B去执行Add函数执行加法操作)
下一篇我会在demo中实现一个使用函数指针的具体功能.