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

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

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C++中實現回調機制的幾種方式[轉]

       
      (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 @ 2013-06-25 10:33  健忘豬  閱讀(392)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 欧美日韩精品一区二区在线观看| 镇远县| 最新国产精品好看的精品| 久久无码中文字幕免费影院蜜桃| 蜜臀av久久国产午夜| 依依成人精品视频在线观看| 伊在人间香蕉最新视频| 亚洲性美女一区二区三区| 精品国产成人三级在线观看| 国产中文字幕精品视频| 国产偷拍自拍视频在线观看| 国产一区在线观看不卡| 特级做a爰片毛片免费看无码| 少妇激情a∨一区二区三区| 视频一区二区三区高清在线| 日韩人妻少妇一区二区三区| 国产不卡免费一区二区| 99久久无码一区人妻a黑| 露脸一二三区国语对白| 亚洲日本欧洲二区精品| 人妻久久久一区二区三区| 无码激情亚洲一区| 欧美xxxx黑人又粗又大| 亚洲精品一区二区三区不| 国产精品久久久久7777| 国产又爽又大又黄a片| 日韩精品一区二区亚洲av| 美女自卫慰黄网站| 女人被狂c躁到高潮视频| 九九热精品在线免费视频| 日韩有码中文字幕国产| 精人妻无码一区二区三区| 亚洲国产一区二区三区久| 国产网友愉拍精品视频手机| 嘉黎县| 成在线人视频免费视频| 亚洲AV天天做在线观看| 国产精品久久久久7777| 久久国产成人高清精品亚洲| 国产成人a在线观看视频免费| 福利在线视频一区二区|