<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發
      海納百川,有容乃大
      在上文 在C++中實現事件(委托) 中我們實現的C#里委托方式的事件處理, 雖然使用很方便,但是感覺似乎少了一點C#的味道, 下面我們嘗試把它改成真正的C#版。

      其實要改成真正的C#版,我們主要要做2件事, 一是吧CEventHandler放到外面,可以讓外部直接構造, 二是實現operator +=和operator -=, 下面是我的實現代碼:
      #pragma once

      #include <functional>
      #include <algorithm>
      #include <vector>
      #include <assert.h>

      namespace Common
      {
          typedef void* cookie_type;

          template<typename TR, typename T1, typename T2>
          class CEventHandler 
          {
          public:
              typedef TR return_type;
              typedef T1 first_type;
              typedef T2 second_type;

              typedef std::function<return_type (first_type, second_type)> handler_type;

              CEventHandler(const CEventHandler& h)
              {
                  _handler = h._handler;
                  assert(_handler != nullptr);
              }

              CEventHandler(handler_type h)
              {
                  _handler = h;
                  assert(_handler != nullptr);
              }

              template<typename class_type, typename class_fun>
              CEventHandler(class_type* pThis, class_fun object_function)
              {
                  using namespace std::placeholders;
                  _handler = std::bind(object_function, pThis, _1, _2);
                  assert(_handler != nullptr);
              }

              return_type operator()(first_type p1, second_type p2)
              {
                  return_type ret = return_type();
                  assert(_handler != nullptr);
                  if(_handler != nullptr) ret = _handler(p1, p2);
                  return ret;
              }

              handler_type _handler;
          };

          template<typename EventHandler>
          class CEvent
          {
          public:
              typedef EventHandler event_handler_type;
              typedef typename event_handler_type::return_type return_type;
              typedef typename event_handler_type::first_type first_type;
              typedef typename event_handler_type::second_type second_type;
              typedef typename event_handler_type::handler_type handler_type;

              ~CEvent()
              {
                  Clear();
              }

              return_type operator()(first_type p1, second_type p2)
              {
                  return_type ret = return_type();
                  size_t size = _handlers.size();
                  for(auto p : _handlers)
                  {
                      ret = p->operator()(p1, p2);
                  }
                  return ret;
              }

              cookie_type AddHandler(const event_handler_type& h)
              {
                  event_handler_type*p = new(nothrow)  event_handler_type(h);
                  if(p != nullptr) _handlers.push_back(p);
                  return (cookie_type)p;
              }

              void RemoveHandler(cookie_type cookie)
              {
                  event_handler_type* p = (event_handler_type*)cookie;

                  auto itr = std::find(_handlers.begin(), _handlers.end(), p);
                  if(itr != _handlers.end())
                  {
                      _handlers.erase(itr);
                      delete p;
                  }
                  else
                  {
                      assert(false);
                  }
              }

              cookie_type operator += (const event_handler_type& pHandler)
              {
                  return AddHandler(pHandler);
              }

              void operator -= (cookie_type cookie)
              {
                  RemoveHandler(cookie);
              }

              void Clear()
              {
                  if(!_handlers.empty())
                  {
                      int n = _handlers.size();
                      std::for_each(_handlers.begin(), _handlers.end(), [](event_handler_type* p)
                      { 
                          assert(p != nullptr);
                          delete p;
                      });
                      _handlers.clear();        
                  }
              }

          private:
              std::vector<event_handler_type*> _handlers;
          };

      //Common

      然后我們就可以這樣使用了:
      // EventTest.cpp : Defines the entry point for the console application.
      //

      #include "stdafx.h"

      #include <iostream>
      #include "event2.h"

      using namespace std;

      class CObjectX 
      {

      };

      class CClickEventArgs: public CObjectX
      {

      };


      class CButton: public CObjectX
      {
      public:
          void FireClick()
          {
              CClickEventArgs args;
              OnClicked(this, args);
          }

          typedef Common::CEventHandler<int, CObjectX*, CClickEventArgs&> ButtonClickEventHandler;
          Common::CEvent<ButtonClickEventHandler> OnClicked;
      };


      class CMyClass 
      {
      public:
          int OnBtuttonClicked(CObjectX* pButton, CClickEventArgs& args)
          {
              cout << "CMyClass: Receive button clicked event" << endl;
              return 1;
          }
      };

      int OnBtuttonClicked_C_fun(CObjectX* pButton, CClickEventArgs& args)
      {
          cout << "C Style Function: Receive button clicked event" << endl;
          return 1;
      }


      class CMyFunObj
      {
      public:
          int operator()(CObjectX* pButton, CClickEventArgs& args)
          {
              cout << "Functor: Receive button clicked event" << endl;
              return 1;    
          }
      };

      int _tmain(int argc, _TCHAR* argv[])
      {
          CButton btn;

          CMyClass obj;
          Common::cookie_type c1 = btn.OnClicked += CButton::ButtonClickEventHandler(&obj, &CMyClass::OnBtuttonClicked);

          Common::cookie_type c2 = btn.OnClicked += CButton::ButtonClickEventHandler(OnBtuttonClicked_C_fun);

          CMyFunObj functor;
          Common::cookie_type c3 = btn.OnClicked += CButton::ButtonClickEventHandler(functor);

          btn.FireClick();

          btn.OnClicked -= c2;

          std::cout << endl;

          btn.FireClick();

          system("pause");

          return 0;
      }

      怎么樣,是不是感覺和C#一樣了 !


      最后,我們比較一下2種實現方式:
      第一種方法把委托函數類型封裝起來了,對外部來說是透明的, 使用起來更簡單。
      第二種方式把委托函數的類型暴露了出來, 適用于事件處理函數類型各異,比較強調事件處理函數類型的場合。

      其實對于C++來說,個人覺得還是第一種方式更合理, 不知道大家怎么看?

       

       注: 如果你不想用C++11的新特性或是你手頭的編譯器不支持C++11, 下面是一種不借助function和bind的實現方式,

          直接用下面的CEventHandler替代上面的就可以了。

       

       

      一種不借助C++11 function和bind的實現方式
      template<typename TR, typename T1, typename T2>
          class CEventHandler
          {
          public:
              typedef TR return_type;
              typedef T1 first_type;
              typedef T2 second_type;

          private:
              class CFunctionBase 
              {
              public:
                  virtual return_type Invoke(first_type p1, second_type p2) = 0;
                  virtual CFunctionBase* Clone() = 0;
                  virtual ~CFunctionBase() { }
              };

              template<typename TFunType>
              class CFunction: public CFunctionBase
              {
              public:
                  CFunction(const TFunType& f): _f(f) { }
                  virtual return_type Invoke(first_type p1, second_type p2)
                  {
                      return _f(p1, p2);
                  }
                  virtual CFunctionBase* Clone()
                  {
                      return new CFunction(this->_f);
                  }

              private:
                  TFunType _f;
              };

              template<typename TClassPtr, typename TMemFunType>
              class CClassMemFun: public CFunctionBase
              {
              public:
                  CClassMemFun(TClassPtr pObj, const TMemFunType& f): _pObj(pObj), _pMemFun(f) { }
                  virtual return_type Invoke(first_type p1, second_type p2)
                  {
                      return ((*_pObj).*_pMemFun)(p1, p2);
                  }
                  virtual CFunctionBase* Clone()
                  {
                      return new CClassMemFun(this->_pObj, this->_pMemFun);
                  }

              private:
                  TClassPtr _pObj;
                  TMemFunType _pMemFun;
              };

          public:
              template<typename TFunType>
              CEventHandler(const TFunType& f): _pFun(new CFunction<TFunType>(f)) { }

              template<typename TClassPtr, typename TMemFunType>
              CEventHandler(TClassPtr pObj, TMemFunType pFun): _pFun(new CClassMemFun<TClassPtr, TMemFunType>(pObj, pFun)) { }

              CEventHandler(const CEventHandler& f)
              {
                  _pFun = f._pFun->Clone(); 
              }

              ~CEventHandler()
              {
                  delete _pFun;
              }

              CEventHandler& operator = (const CEventHandler& f)
              {
                  if(this != &f)
                  {
                      delete _pFun;
                      _pFun = f._pFun->Clone(); 
                  }

                  return *this;
              }

              return_type operator()(first_type p1, second_type p2)
              {
                  return_type ret = return_type();
                  if(_pFun != nullptr)
                  {
                      _pFun->Invoke(p1, p2);
                  }
                  else
                  {
                      assert(false);
                  }

                  return ret;
              }

          private:
              CFunctionBase* _pFun;

      posted on 2013-01-31 17:46  Richard Wei  閱讀(3003)  評論(5)    收藏  舉報

      主站蜘蛛池模板: 中文字日产幕码三区国产| 无码人妻aⅴ一区二区三区蜜桃| 色综合久久综合香蕉色老大| 少妇又爽又刺激视频| 动漫av纯肉无码av在线播放| 日韩永久永久永久黄色大片| 欧洲精品久久久AV无码电影| 成人av午夜在线观看| 中文字幕久久波多野结衣av| 亚洲AV无码专区亚洲AV桃 | 最近中文字幕日韩有码| 国产精品无码不卡在线播放| 又粗又大又黄又硬又爽免费看| 苏尼特左旗| 久久婷婷大香萑太香蕉AV人| 国产一区二区三区小说| 热久在线免费观看视频| 在线成人国产天堂精品av| 97精品伊人久久久大香线蕉| 蜜桃av无码免费看永久| 亚洲大尺度视频在线播放| 久久综合国产色美利坚| 久久人人97超碰精品| 国产精品三级中文字幕| 激情 小说 亚洲 图片 伦| 成人毛片100免费观看| 色婷婷亚洲精品综合影院| 亚洲国产亚洲综合在线尤物| 99在线 | 亚洲| 中文国产日韩欧美二视频| 乱色老熟妇一区二区三区| 少妇被无套内谢免费看| 安丘市| 免费人妻av无码专区| 国产睡熟迷奷系列网站| 看亚洲黄色不在线网占| 丝袜欧美视频首页在线| 成人网站国产在线视频内射视频| 久久发布国产伦子伦精品| 久久免费观看归女高潮特黄| 亚洲综合精品第一页|