您的位置:首页 > 其它

回调函数的使用封装(支持全局函数,类静态函数,类成员函数)

2012-11-26 12:23 375 查看
回调函数的使用封装在了callback.h中,main.cpp用于测试回调。

Ref CEGUI。。。

callback.h (回调封装)

#######################################

/*

**FileName: callback.h

**Description: 回调函数机制封装(支持类成员函数与全局函数)

**Autor: by Roobt

**Create Time: 2012/11/26 10:34

*/

#ifndef __CALLBACK_H__

#define __CALLBACK_H__

#include <map>

using std::map;

using std::make_pair;

typedef int EventArgs;

typedef int EventID;

//回调基类

class SlotFunctorBase

{

public:

virtual ~SlotFunctorBase() {};

//使用操作符来调用函数

virtual bool operator()(const EventArgs& args) = 0;

};

//全局函数、静态函数或类的静态成员函数做回调

class FreeFunctionSlot : public SlotFunctorBase

{

public:

//定义回调函数的格式

typedef bool (SlotFunction)(const EventArgs&); //函数指针

public:

FreeFunctionSlot(SlotFunction* func) : d_function(func)

{}

virtual bool operator()(const EventArgs& args)

{

return d_function(args);

}

private:

SlotFunction* d_function;

};

//类的普通成员函数做回调

template<typename T>

class MemberFunctionSlot : public SlotFunctorBase

{

public:

//!成员变量的回调函数定义

typedef bool (T::*MemberFunctionType)(const EventArgs&); //类的成员函数指针的类型

public:

MemberFunctionSlot(MemberFunctionType func, T* obj) :

d_function(func), d_object(obj)

{}

virtual bool operator()(const EventArgs& args)

{

return (d_object->*d_function)(args); //调用类的成员函数

}

private:

MemberFunctionType d_function;

T* d_object;

};

//对上面2种实现的封装

class SubscriberSlot

{

public:

//默认构造函数

SubscriberSlot()

{

d_functor_impl = NULL;

}

//标准析构函数

~SubscriberSlot()

{

delete d_functor_impl;

d_functor_impl = NULL;

}

//调用函数的()重载,具体由第一类Functor实现

bool operator()(const EventArgs& args) const

{

return (*d_functor_impl)(args);

}

//返回成员是否有效,是否已经连接到一个具体的Functor实现

bool connected() const

{

return d_functor_impl != NULL;

}

//FreeFunctionSlot,自由函数的封装类

SubscriberSlot(FreeFunctionSlot::SlotFunction* func) :

d_functor_impl(new FreeFunctionSlot(func))

{}

// 模板构造函数,以成员函数的封装为参数,MemberFunctionSlot。

template<typename T>

SubscriberSlot(bool (T::*function)(const EventArgs&), T* obj) :

d_functor_impl(new MemberFunctionSlot<T>(function, obj))

{}

private:

//内部基本Functor的指针,SlotFunctorBase基类的优势在这里用到了

SlotFunctorBase* d_functor_impl;

};

// 注册函数宏

// 注册全局函数、类静态成员函数作为回调函数

#define REGISTER_FUNC(id, subscribeSlot, func, q) \

SubscriberSlot* subscribeSlot = new SubscriberSlot((FreeFunctionSlot::SlotFunction*)&func);\

q->subscribe(id, subscribeSlot);

// 注册类成员函数作为回调函数

// param0: 事件id

// param1: psubscribeSlot, 随便一个变量名

// param2: func, 要注册的类的普通成员函数(即:回调函数)

// param3: p, func所在类的一个实例指针

// param4: q, 注册类(调用注册函数的类)的一个实例指针

#define REGISTER_OBJFUNC(id, subscribeSlot, func, p, q) \

SubscriberSlot* subscribeSlot = new SubscriberSlot(&func, p);\

q->subscribe(id, subscribeSlot);

// 回调

class Callback

{

public:

typedef map<EventID, SubscriberSlot*> EventMap;

public:

Callback() {eventList.clear();}

~Callback() {eventList.clear();}

bool subscribe(EventID id, SubscriberSlot* subscriberSlot)

{

if (NULL == subscriberSlot)

return false;

EventMap::iterator iter = eventList.find(id);

if (iter != eventList.end())

return false;

eventList.insert(make_pair(id, subscriberSlot));

return true;

}

bool evoke(EventID id)

{

EventMap::iterator iter = eventList.find(id);

if(iter == eventList.end())

return false;

SubscriberSlot* subscribeSlot = eventList[id];

if (subscribeSlot)

{

EventArgs args = 0;

(*subscribeSlot)(args);

return true;

}

return false;

}

private:

EventMap eventList;

};

#endif

#######################################

main.cpp (测试)

######################################

#include "stdafx.h"

#include "callback.h"

#include <iostream>

using namespace std;

class A

{

public:

bool Test1(const EventArgs&)

{

cout<<"Test1..."<<endl;

return true;

}

static bool Test2(const EventArgs&)

{

cout<<"Test2..."<<endl;

return true;

}

};

class B : public Callback

{

public:

enum EVENT_TYPE

{

EVENT_TYPE_INVALID = -1,

EVENT_TYPE1,

EVENT_TYPE2,

EVENT_TYPE_NUMBER,

};

public:

B(A *pA) : m_pAObj(pA)

{}

void registerCallback()

{

// 类成员函数

REGISTER_OBJFUNC(EVENT_TYPE1, subscribeSlot, A::Test1, m_pAObj, this);

// 类静态函数

REGISTER_FUNC(EVENT_TYPE2, subscribeSlot2, A::Test2, this);

}

void evoke()

{

Callback::evoke(EVENT_TYPE1);

Callback::evoke(EVENT_TYPE2);

}

private:

A *m_pAObj;

};

// 主函数

int _tmain(int argc, _TCHAR* argv[])

{

A *pA = new A();

B *pB = new B(pA);

if (pB)

{

pB->registerCallback();

pB->evoke();

}

system("pause");

return 0;

}

######################################
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: