用C++模拟C#事件机制之改进篇

我前面写过的一篇 C++模拟C#事件机制 中给出了一个C++ event完整实现, 但是存在好多问题,主要是:由于使用静态变量存储函数类别导致不能保存多个相同函数特征(参数列表和返回值)的函数。这个重构版本充分利用了面向对象的思想,利用派生和多态封装了全局函数,成员函数,函数对象,使3者借口完全一致.

 

 

template<class TReturn, class TArgument> class BaseInvoker { public:  BaseInvoker(){}  virtual ~BaseInvoker(){} public:  virtual TReturn invoke(TArgument args) = 0; }; template<class TReturn, class TArgument> class GlobalInvoker : public BaseInvoker { public:  typedef TReturn (*Method)(TArgument args); public:  GlobalInvoker(Method pCallback)  :mCallback(pCallback)  {  }  virtual TReturn invoke(TArgument args)  {   return mCallback(args);  } private:  Method mCallback; }; template<class TObject, class TReturn, class TArgument> class MemberInvoker : public BaseInvoker { public:  typedef TReturn (TObject::*MemberMethod)(TArgument); public:  MemberInvoker(TObject* pObject,MemberMethod pCallback)  :mObject(pObject), mCallback(pCallback)  {  }  virtual TReturn invoke(TArgument args)  {   return (mObject->*mCallback)(args);  } private:  TObject*  mObject;  MemberMethod mCallback; }; template<class TFunctor, class TReturn, class TArgument> class FunctorInvoker : public BaseInvoker { public:  typedef TFunctor* FunctorMethod; public:  FunctorInvoker(FunctorMethod pCallback)  :mCallback(pCallback)  {  }  virtual TReturn invoke(TArgument args)  {   return mCallback(args);  } private:  FunctorMethod mCallback; };

delegate使用智能指针shared_ptr存储实际的函数类型(智能指针可以自己实现,也可以用boost::shared_ptr, std::tr1::shread_ptr,我这里使用的是OGRE自带的一个只能指针,其实自己写也不难),以确保安全性,

相应的,delagate构造函数也要改一下:

 

 

  1. template<class TReturn, class TArgument>
  2. class Delegate  
  3. {
  4. public:
  5.  virtual ~Delegate()
  6.  {
  7.  }
  8. public:
  9.  template<class TReturn, class TArgument>
  10.  friend bool operator==(Delegate const& lhs, Delegate const& rhs);
  11.  // for global or static methods
  12.  Delegate(TReturn (*pCallback)(TArgument))
  13.  :mInvoker(new GlobalInvoker(pCallback))
  14.  {
  15.  } 
  16.  // for object member methods
  17.  template<class TObject>
  18.  Delegate(TObject* pObject, TReturn (TObject::*pCallback)(TArgument))
  19.  :mInvoker(new MemberInvoker(pObject,pCallback))
  20.  {
  21.   
  22.  }
  23.  // for functor methods
  24.  template<class TFunctor>
  25.  Delegate(TFunctor* pCallback)
  26.  :mInvoker(new FunctorInvoker(pCallback))
  27.  {
  28.  }
  29.  TReturn operator() (TArgument args)
  30.  {
  31.   return mInvoker->invoke(args);
  32.  }
  33.  //implementations
  34. private:
  35.  Ogre::SharedPtr > mInvoker;
  36. // unsigned int mReference;
  37. };

delegate对外接口没有改变因此event及使用event的代码 无需改变,这也充分说明了抽象的好处:实现不论怎么变化,但接口不便。

你可能感兴趣的:(C++,c#,c++,存储,c)