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

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

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發(fā)
      海納百川,有容乃大
      C++中實(shí)現(xiàn)回調(diào)機(jī)制的幾種方式一文中,我們提到了實(shí)現(xiàn)回調(diào)的三種方式(C風(fēng)格的回調(diào)函數(shù), Sink方式和Delegate方式)。在面向?qū)ο箝_(kāi)發(fā)中,delegate的方式是最靈活和方便的,因此很早就有人用復(fù)雜的模板去模擬(有興趣的話可以看這里這里),總之是實(shí)現(xiàn)起來(lái)很復(fù)雜。但是現(xiàn)在借助C++11的functionbind, 我們可以很方便的去實(shí)現(xiàn)。下面是我自己的一種實(shí)現(xiàn)方式:
        namespace Common
      {
          typedef void* cookie_type;

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

              typedef std::function<return_type (first_type, second_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(size_t i=0; i<size; ++i)
                  {
                      ret = _handlers[i]->operator()(p1, p2);
                  }
                  return ret;
              }

              cookie_type AddHandler(std::function<return_type (first_type, second_type)> h)
              {
                  CEventHandler*p = new(nothrow)  CEventHandler(h);
                  if(p != nullptr) _handlers.push_back(p);
                  return (cookie_type)p;
              }

              template<typename class_type, typename class_fun>
              cookie_type AddHandler(class_type* pThis, class_fun f)
              {
                  CEventHandler* p = new(nothrow) CEventHandler(pThis, f);
                  if(p != nullptr) _handlers.push_back(p);
                  return (cookie_type)p;
              }

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

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

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

          private:
              class CEventHandler 
              {
              public:
                  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;
              };


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

      大概實(shí)現(xiàn)思想是我們通過(guò)一個(gè)內(nèi)置的CEventHandler 類來(lái)封裝處理函數(shù),我們可以通過(guò)AddHandler來(lái)添加事件處理函數(shù),添加時(shí)會(huì)返回一個(gè)Cookie,我們可以通過(guò)該Cookie來(lái)RemoveHandler, 下面是測(cè)試代碼:
      #include "stdafx.h"
      #include <iostream>
      #include "event1.h"

      using namespace std;

      class CObjectX 
      {

      };

      class CClickEventArgs: public CObjectX
      {

      };


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

          Common::CEvent<int, CObjectX*, CClickEventArgs&> 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[])
      {
          using namespace std::placeholders;

          CButton btn;

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

          Common::cookie_type c2 = btn.OnClicked.AddHandler(OnBtuttonClicked_C_fun);

          CMyFunObj functor;
          Common::cookie_type c3 = btn.OnClicked.AddHandler(functor);

          btn.FireClick();


          btn.OnClicked.RemoveHandler(c2);

          std::cout << endl;


          btn.FireClick();

          system("pause");

          return 0;
      }

      以下是測(cè)試結(jié)果:


       可以看到, 我們?cè)谄胀–函數(shù), 類成員函數(shù)和仿函數(shù)(functor)中都測(cè)試通過(guò)。

      另外對(duì)于事件函數(shù)返回值為void的情況,會(huì)編譯出錯(cuò),我們需要偏特化一下:
          template< typename T1, typename T2>
          class CEvent<void, T1, T2>
          {
          public:
              typedef void return_type;
              typedef T1 first_type;
              typedef T2 second_type;

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

              ~CEvent()
              {
                  Clear();
              }

              return_type operator()(first_type p1, second_type p2)
              {
                  size_t size = _handlers.size();
                  for(size_t i=0; i<size; ++i)
                  {
                      _handlers[i]->operator()(p1, p2);
                  }
              }

              cookie_type AddHandler(std::function<return_type (first_type, second_type)> h)
              {
                  CEventHandler*p = new(nothrow)  CEventHandler(h);
                  if(p != nullptr) _handlers.push_back(p);
                  return (cookie_type)p;
              }

              template<typename class_type, typename class_fun>
              cookie_type AddHandler(class_type* pThis, class_fun f)
              {
                  CEventHandler* p = new(nothrow) CEventHandler(pThis, f);
                  if(p != nullptr) _handlers.push_back(p);
                  return (cookie_type)p;
              }

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

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

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

          private:
              class CEventHandler 
              {
              public:
                  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)
                  {
                      assert(_handler != nullptr);
                      if(_handler != nullptr) _handler(p1, p2);
                  }

                  handler_type _handler;
              };


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

      最后談一下在寫這個(gè)代碼中遇到的問(wèn)題:
      (1)不知道你能不能發(fā)現(xiàn)下面代碼的問(wèn)題, 我在寫代碼時(shí)就栽在這里了:
           vector<int*>  v;
          int* p1 = new int(1);
          v.push_back(p1);
          int* p2 = new int(2);
          v.push_back(p2);
       
          //嘗試刪除所有值為p1的項(xiàng)
          //由該代碼想到=>v.erase(std::remove(v.begin(), v.end(), p1), v.end());
          auto itr = remove(v.begin(), v.end(), p1);
          for_each(itr, v.end(), [](int* p){delete p;});
          v.erase(itr, v.end());

      (2)我們想把cookei_type放到類里面去, 類似這樣:
      1     template<typename TR, typename T1, typename T2>
      2     class CEvent
      3     {
      4     public:
      5         typedef TR return_type;
      6         typedef T1 first_type;
      7         typedef T2 second_type;
      8         typedef void* cookie_type;

      可發(fā)現(xiàn)要這樣使用:
      Common::CEvent<int, CObjectX*, CClickEventArgs&>::cookie_type c1 = btn.OnClicked.AddHandler(&obj, &CMyClass::OnBtuttonClicked);
      太不方便了, 不知道大家有沒(méi)有好的方法。

      注:上面的代碼還沒(méi)有經(jīng)過(guò)真正商業(yè)使用,如果有問(wèn)題歡迎指出。
      posted on 2013-01-31 14:23  Richard Wei  閱讀(2570)  評(píng)論(2)    收藏  舉報(bào)

      主站蜘蛛池模板: 性男女做视频观看网站| 人人超人人超碰超国产| 国产精品黄色片| 1区2区3区4区产品不卡码网站| 福利一区二区不卡国产| 热久久99精品这里有精品| 精品乱码一区二区三四五区 | 亚洲深深色噜噜狠狠网站| 日本一区二区久久人妻高清| 亚洲av无码专区在线亚| 亚洲国产一区二区三区| 麻豆国产va免费精品高清在线| 久章草在线精品视频免费观看| 国产精品一亚洲av日韩| 中文字幕结果国产精品| 国产精品久久久久影院老司| 国产99久久精品一区二区| 波多野结衣久久一区二区| 国产卡一卡二卡三免费入口| 91亚洲国产成人久久精| 亚洲av日韩av永久无码电影| 亚洲国产精品高清线久久| 国产精品不卡一二三区| 艳妇臀荡乳欲伦69调教视频| 国产乱妇无乱码大黄aa片| 国产中文字幕一区二区| 麻豆国产成人av高清在线| 57pao成人国产永久免费视频 | 99精品国产一区二区三| 少妇人妻偷人偷人精品| 久久婷婷五月综合色欧美| 国产在线精彩自拍视频| 日本一道一区二区视频| 湘阴县| 国产一区二区三区禁18| 国产一码二码三码区别| 国产免费久久精品44| 饥渴的熟妇张开腿呻吟视频| 亚洲综合国产激情另类一区| 久久天天躁夜夜躁狠狠85| 四虎永久精品免费视频|