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

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

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      厚積薄發
      海納百川,有容乃大
      (1)Callback方式
      Callback的本質是設置一個函數指針進去,然后在需要需要觸發某個事件時調用該方法, 比如Windows的窗口消息處理函數就是這種類型。

      比如下面的示例代碼,我們在Download完成時需要觸發一個通知外面的事件:
      typedef void (__stdcall *DownloadCallback)(const char* pURL, bool bOK);
      void DownloadFile(const char* pURL, DownloadCallback callback)
      {
          cout << "downloading: " << pURL << "" << endl;
          callback(pURL, true);
      }
      void __stdcall OnDownloadFinished(const char* pURL, bool bOK)
      {
          cout << "OnDownloadFinished, URL:" << pURL << "    status:" << bOK << endl;
      }

      (2)Sink方式
      Sink的本質是你按照對方要求實現一個C++接口,然后把你實現的接口設置給對方,對方需要觸發事件時調用該接口, COM中連接點就是居于這種方式。

      上面下載文件的需求,如果用Sink實現,代碼如下:
      class IDownloadSink
      {
      public:
          virtual void OnDownloadFinished(const char* pURL, bool bOK) = 0;
      };
      class CMyDownloader
      {
      public:
          CMyDownloader(IDownloadSink* pSink)
              :m_pSink(pSink)
          {
          }

          void DownloadFile(const char* pURL)
          {
              cout << "downloading: " << pURL << "" << endl;
              if(m_pSink != NULL)
              {
                  m_pSink->OnDownloadFinished(pURL, true);
              }
          }

      private:
          IDownloadSink* m_pSink;
      };

      class CMyFile: public IDownloadSink
      {
      public:
          void download()
          {
              CMyDownloader downloader(this);
              downloader.DownloadFile("www.baidu.com");
          }

          virtual void OnDownloadFinished(const char* pURL, bool bOK)
          {
              cout << "OnDownloadFinished, URL:" << pURL << "    status:" << bOK << endl;
          }
      };

      (3)Delegate方式
      Delegate的本質是設置成員函數指針給對方,然后讓對方在需要觸發事件時調用。
      C#中用Delegate的方式實現Event,讓C++程序員很是羨慕,C++中因為語言本身的關系,要實現Delegate還是很麻煩的。
      上面的例子我們用Delegate的方式實現如下: 
      class CDownloadDelegateBase
      {
      public:
          virtual void Fire(const char* pURL, bool bOK) = 0;
      };

      template<typename O, typename T>
      class CDownloadDelegate: public CDownloadDelegateBase
      {
          typedef void (T::*Fun)(const char*, bool);
      public:
          CDownloadDelegate(O* pObj = NULL, Fun pFun = NULL)
              :m_pFun(pFun), m_pObj(pObj)
          {
          }
          
          virtual void Fire(const char* pURL, bool bOK)
          {
              if(m_pFun != NULL
                  && m_pObj != NULL)
              {
                  (m_pObj->*m_pFun)(pURL, bOK);
              }
          }

      private:
          Fun m_pFun;
          O* m_pObj;
      };

      template<typename O, typename T>
      CDownloadDelegate<O,T>* MakeDelegate(O* pObject, void (T::*pFun)(const char* pURL, bool))
      {
          return new CDownloadDelegate<O, T>(pObject, pFun);
      }

      class CDownloadEvent
      {
      public:
          ~CDownloadEvent()
          {
              vector<CDownloadDelegateBase*>::iterator itr = m_arDelegates.begin();
              while (itr != m_arDelegates.end())
              {
                  delete *itr;
                  ++itr;
              }
              m_arDelegates.clear();
          }

          void operator += (CDownloadDelegateBase* p)
          {
              m_arDelegates.push_back(p);
          }

          void operator -= (CDownloadDelegateBase* p)
          {
              ITR itr = remove(m_arDelegates.begin(), m_arDelegates.end(), p);

              ITR itrTemp = itr;
              while (itrTemp != m_arDelegates.end())
              {
                  delete *itr;
                  ++itr;
              }
              m_arDelegates.erase(itr, m_arDelegates.end());
          }

          void operator()(const char* pURL, bool bOK)
          {
              ITR itrTemp = m_arDelegates.begin();
              while (itrTemp != m_arDelegates.end())
              {
                  (*itrTemp)->Fire(pURL, bOK);
                  ++itrTemp;
              }
          }

      private:
          vector<CDownloadDelegateBase*> m_arDelegates;
          typedef vector<CDownloadDelegateBase*>::iterator ITR;
      };


      class CMyDownloaderEx
      {
      public:
          void DownloadFile(const char* pURL)
          {
              cout << "downloading: " << pURL << "" << endl;
              downloadEvent(pURL, true);
          }

          CDownloadEvent downloadEvent;
      };

      class CMyFileEx
      {
      public:
          void download()
          {
              CMyDownloaderEx downloader;
              downloader.downloadEvent += MakeDelegate(this, &CMyFileEx::OnDownloadFinished);
              downloader.DownloadFile("www.baidu.com");
          }

          virtual void OnDownloadFinished(const char* pURL, bool bOK)
          {
              cout << "OnDownloadFinished, URL:" << pURL << "    status:" << bOK << endl;
          }
      };

      可以看到Delegate的方式代碼量比上面其他2種方式大多了,并且我們上面是固定參數數量和類型的實現方式,如果要實現可變參數,要更加麻煩的多。
      可變參數的方式可以參考這2種實現:
      Yet Another C#-style Delegate Class in Standard C++
      Member Function Pointers and the Fastest Possible C++ Delegates


      我們可以用下面的代碼測試我們上面的實現:
      int _tmain(int argc, _TCHAR* argv[])
      {

          DownloadFile("www.baidu.com", OnDownloadFinished);

          CMyFile f1;
          f1.download();

          CMyFileEx ff;
          ff.download();

          system("pause");

          return 0;
      }


      最后簡單比較下上面3種實現回調的方法:
      第一種Callback的方法是面向過程的,使用簡單而且靈活,正如C語言本身。
      第二種Sink的方法是面向對象的,在C++里使用較多, 可以在一個Sink里封裝一組回調接口,適用于一系列比較固定的回調事件。
      第三種Delegate的方法也是面向對象的,和Sink封裝一組接口不同,Delegate的封裝是以函數為單位,粒度比Sink更小更靈活。 

      你更傾向于用哪種方式來實現回調?
      posted on 2012-08-28 12:43  Richard Wei  閱讀(10043)  評論(9)    收藏  舉報

      主站蜘蛛池模板: 久久天天躁狠狠躁夜夜婷| 国产又色又爽又黄的网站免费| 久久精品99国产精品日本| 日韩人妻无码一区二区三区综合部| 国产精品一二二区视在线| 婷婷国产成人精品视频| 亚洲精品一区二区三区综合 | 精品乱码一区二区三四五区| 国产色无码专区在线观看| 又爽又黄又无遮掩的免费视频| 久青草国产在视频在线观看| 韩国无码AV片午夜福利| 国产午夜精品理论大片| 欧美男男作爱videos可播放| 国产精品+日韩精品+在线播放| 亚洲中少妇久久中文字幕| 久久精品国产亚洲av热一区| 亚洲国产免费图区在线视频| 久久国内精品自在自线91| 亚洲综合伊人五月天中文| 日韩 欧美 亚洲 一区二区| 国产丝袜肉丝视频在线| 久久无码中文字幕免费影院蜜桃| 亚洲国产精品久久久天堂麻豆宅男| 激情欧美日韩一区二区| 91老肥熟女九色老女人| 亚洲精品一区二区区别| 中文字幕国产在线精品| 制服丝袜人妻有码无码中文字幕| 成人性影院| 少妇人妻偷人精品免费| 久久狠狠高潮亚洲精品| 亚洲中文字幕一区二区| 堆龙德庆县| 在线 欧美 中文 亚洲 精品| 日韩内射美女人妻一区二区三区| 91产精品无码无套在线| 国产精品一区 在线播放| 五月综合激情婷婷六月| 色综合夜夜嗨亚洲一二区| 一本av高清一区二区三区|