天天看點

回調函數的使用封裝(支援全局函數,類靜态函數,類成員函數)

回調函數的使用封裝在了callback.h中,main.cpp用于測試回調。

Ref  CEGUI。。。

callback.h (回調封裝)

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

#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;

}

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

繼續閱讀