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

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

 

 

  1. template<class TReturn, class TArgument>
  2. class BaseInvoker
  3. {
  4. public:
  5.  BaseInvoker(){}
  6.  virtual ~BaseInvoker(){}
  7. public:
  8.  virtual TReturn invoke(TArgument args) = 0;
  9. };
  10. template<class TReturn, class TArgument>
  11. class GlobalInvoker : public BaseInvoker<TReturn, TArgument>
  12. {
  13. public:
  14.  typedef TReturn (*Method)(TArgument args);
  15. public:
  16.  GlobalInvoker(Method pCallback)
  17.  :mCallback(pCallback)
  18.  {
  19.  }
  20.  virtual TReturn invoke(TArgument args)
  21.  {
  22.   return mCallback(args);
  23.  }
  24. private:
  25.  Method mCallback;
  26. };
  27. template<class TObject, class TReturn, class TArgument>
  28. class MemberInvoker : public BaseInvoker<TReturn, TArgument>
  29. {
  30. public:
  31.  typedef TReturn (TObject::*MemberMethod)(TArgument);
  32. public:
  33.  MemberInvoker(TObject* pObject,MemberMethod pCallback)
  34.  :mObject(pObject), mCallback(pCallback)
  35.  {
  36.  }
  37.  virtual TReturn invoke(TArgument args)
  38.  {
  39.   return (mObject->*mCallback)(args);
  40.  }
  41. private:
  42.  TObject*  mObject;
  43.  MemberMethod mCallback;
  44. };
  45. template<class TFunctor, class TReturn, class TArgument>
  46. class FunctorInvoker : public BaseInvoker<TReturn, TArgument>
  47. {
  48. public:
  49.  typedef TFunctor* FunctorMethod;
  50. public:
  51.  FunctorInvoker(FunctorMethod pCallback)
  52.  :mCallback(pCallback)
  53.  {
  54.  }
  55.  virtual TReturn invoke(TArgument args)
  56.  {
  57.   return mCallback(args);
  58.  }
  59. private:
  60.  FunctorMethod mCallback;
  61. };

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<TReturn, TArgument> const& lhs, Delegate<TReturn, TArgument> const& rhs);
  11.  // for global or static methods
  12.  Delegate(TReturn (*pCallback)(TArgument))
  13.  :mInvoker(new GlobalInvoker<TReturn, TArgument>(pCallback))
  14.  {
  15.  } 
  16.  // for object member methods
  17.  template<class TObject>
  18.  Delegate(TObject* pObject, TReturn (TObject::*pCallback)(TArgument))
  19.  :mInvoker(new MemberInvoker<TObject,TReturn,TArgument>(pObject,pCallback))
  20.  {
  21.   
  22.  }
  23.  // for functor methods
  24.  template<class TFunctor>
  25.  Delegate(TFunctor* pCallback)
  26.  :mInvoker(new FunctorInvoker<TFunctor,TReturn,TArgument>(pCallback))
  27.  {
  28.  }
  29.  TReturn operator() (TArgument args)
  30.  {
  31.   return mInvoker->invoke(args);
  32.  }
  33.  //implementations
  34. private:
  35.  Ogre::SharedPtr<BaseInvoker<TReturn, TArgument> > mInvoker;
  36. // unsigned int mReference;
  37. };

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值