回调函数的使用封装(支持全局函数,类静态函数,类成员函数)
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;
}
######################################
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;
}
######################################
相关文章推荐
- 让C++回调函数可以同时支持成员函数和静态函数的方法
- C++中 线程函数为静态函数 及 类成员函数作为回调函数
- 在封装的静态成员函数中使用类指针
- 使用类的成员函数作为API定时器的回调函数
- 回调函数的C++ 封装(非静态成员函数的回调函数实现方法)
- C++模板技术之method_thunk, 使用场景: C++中类成员函数作为回调函数
- 学生类封装 , (链表)插入排序成绩 无动态数组 ,动态开辟空间 以及静态函数,数据成员的使用
- 《PCL点云库学习&VS2010(X64)》Part 29 PCL使用类成员函数作为pclvisualizer的回调函数
- C++中 线程函数为静态函数 及 类成员函数作为回调函数
- C++中 线程函数为静态函数 及 类成员函数作为回调函数
- PCL使用类成员函数作为pclvisualizer的回调函数
- 在C++的类中使用类成员函数作为回调函数
- 在模板类成员函数入参中使用回调函数指针
- 使用C++类成员函数作为回调函数
- 使用类的成员函数来实现回调函数
- C++中使用空对象指针调用成员函数
- string基本的类成员函数的使用(at、length、size、begin、empty、resize)
- C++成员函数指针的使用方法
- 如何定义和实现一个类的成员函数为回调函数
- 浅析在类模版中构建成员函数时,使用memcpy产生的副作用