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

本文介绍了一种在C++中封装回调函数的方法,支持类成员函数及全局函数,并通过示例展示了如何使用该封装进行事件订阅与触发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

回调函数的使用封装在了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;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值