青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

面對現(xiàn)實,超越自己
逆水行舟,不進則退
posts - 269,comments - 32,trackbacks - 0
1、Callback方式

Callback的本質(zhì)是設(shè)置一個函數(shù)指針進去,然后在需要需要觸發(fā)某個事件時調(diào)用該方法, 比如Windows的窗口消息處理函數(shù)就是這種類型。

比如下面的示例代碼,我們在Download完成時需要觸發(fā)一個通知外面的事件:
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的本質(zhì)是你按照對方要求實現(xiàn)一個C++接口,然后把你實現(xiàn)的接口設(shè)置給對方,對方需要觸發(fā)事件時調(diào)用該接口, COM中連接點就是居于這種方式。

上面下載文件的需求,如果用Sink實現(xiàn),代碼如下:
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的本質(zhì)是設(shè)置成員函數(shù)指針給對方,然后讓對方在需要觸發(fā)事件時調(diào)用。
C#中用Delegate的方式實現(xiàn)Event,讓C++程序員很是羨慕,C++中因為語言本身的關(guān)系,要實現(xiàn)Delegate還是很麻煩的。
上面的例子我們用Delegate的方式實現(xiàn)如下: 
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種方式大多了,并且我們上面是固定參數(shù)數(shù)量和類型的實現(xiàn)方式,如果要實現(xiàn)可變參數(shù),要更加麻煩的多。
可變參數(shù)的方式可以參考這2種實現(xiàn):
Yet Another C#-style Delegate Class in Standard C++
Member Function Pointers and the Fastest Possible C++ Delegates


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

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

    CMyFile f1;
    f1.download();

    CMyFileEx ff;
    ff.download();

    system("pause");

    return 0;
}


最后簡單比較下上面3種實現(xiàn)回調(diào)的方法:
第一種Callback的方法是面向過程的,使用簡單而且靈活,正如C語言本身。
第二種Sink的方法是面向?qū)ο蟮模贑++里使用較多, 可以在一個Sink里封裝一組回調(diào)接口,適用于一系列比較固定的回調(diào)事件。
第三種Delegate的方法也是面向?qū)ο蟮模蚐ink封裝一組接口不同,Delegate的封裝是以函數(shù)為單位,粒度比Sink更小更靈活。 

你更傾向于用哪種方式來實現(xiàn)回調(diào)?

本文轉(zhuǎn)自:http://m.shnenglu.com/weiym/archive/2012/08/28/188515.html
posted on 2012-09-11 10:43 王海光 閱讀(458) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久免费视频网| 一本色道久久88综合亚洲精品ⅰ| 欧美四级电影网站| 亚洲欧洲日本在线| 久久青草久久| 久久免费国产| 国产性天天综合网| 欧美+日本+国产+在线a∨观看| 一本色道久久综合亚洲二区三区| 亚洲欧洲精品一区二区| 欧美日韩中文在线观看| 亚洲欧美日韩国产中文| 久久精品国产2020观看福利| 国内一区二区在线视频观看| 久久国产日本精品| 亚洲精品九九| 亚洲网站在线观看| 韩日成人在线| 欧美精品日韩三级| 久久综合网络一区二区| 一本久道久久综合婷婷鲸鱼| 久久aⅴ国产紧身牛仔裤| 亚洲人成毛片在线播放女女| 黑人巨大精品欧美一区二区| 久久亚洲精品一区二区| 久久精品在这里| 亚洲美女av在线播放| 欧美激情一区二区三区成人| 久久国产精品一区二区| 久久黄金**| 久久久久久69| 久久久在线视频| 欧美区日韩区| 欧美午夜视频| 欧美日韩国内| 欧美久久一级| 欧美日韩精品伦理作品在线免费观看 | 久久中文字幕一区二区三区| 亚洲综合首页| 一区二区欧美亚洲| 日韩一二在线观看| 亚洲一区二区成人| 在线亚洲一区观看| 欧美中文字幕在线| 欧美成人a视频| 欧美1区免费| 欧美极品一区二区三区| 亚洲福利视频网站| 新狼窝色av性久久久久久| 欧美成人精品在线视频| 久久久久久亚洲精品中文字幕| 亚洲电影天堂av| 在线日韩中文| 中日韩午夜理伦电影免费| 亚洲香蕉伊综合在人在线视看| 欧美综合第一页| 99视频有精品| 久久午夜激情| 欧美日韩无遮挡| 亚洲国产第一| 免费观看久久久4p| 久久亚洲精品一区| 一区二区三区中文在线观看 | 国产欧美日韩亚洲| 一区二区三区在线高清| 亚洲欧美综合v| 久久综合九色99| 亚洲三级影院| 鲁大师成人一区二区三区| 国产精品入口麻豆原神| 亚洲国产经典视频| 欧美大胆a视频| 一级日韩一区在线观看| 欧美激情麻豆| 日韩一区二区福利| 亚洲国产天堂久久国产91| 久久精品国产清高在天天线| 亚洲一区二区在线观看视频| 欧美日韩一级片在线观看| 亚洲日韩中文字幕在线播放| 噜噜噜躁狠狠躁狠狠精品视频| 久久er精品视频| 国产亚洲成年网址在线观看| 久久成人18免费观看| 欧美一区2区三区4区公司二百| 国产综合亚洲精品一区二| 亚洲男女自偷自拍| 91久久香蕉国产日韩欧美9色| 蜜桃av久久久亚洲精品| 亚洲欧洲日本专区| 在线视频你懂得一区| 伊人色综合久久天天| 亚洲国产成人精品女人久久久| 欧美日韩在线高清| 亚洲一本视频| 欧美v日韩v国产v| 亚洲天堂成人| 噜噜噜91成人网| 亚洲欧美韩国| 欧美电影美腿模特1979在线看| 韩国av一区| 亚洲人成人77777线观看| 国产精品羞羞答答xxdd| 亚洲一区二区三区在线| 久久综合狠狠| 欧美成人黑人xx视频免费观看| 亚洲自拍偷拍麻豆| 久久精品国产亚洲aⅴ| 亚洲淫性视频| 国产精品a久久久久| 亚洲精品综合久久中文字幕| 国产亚洲一区二区三区在线观看 | 99国产精品久久久久久久| 国产一区二区三区观看| 一本一本a久久| 欧美亚洲免费电影| 欧美偷拍一区二区| 欧美不卡高清| 国产午夜精品麻豆| 99精品视频免费| 亚洲欧美日韩精品| 久久免费视频在线观看| 亚洲国产第一| 亚洲第一狼人社区| 欧美高清hd18日本| 麻豆久久婷婷| 91久久精品一区二区三区| 久久久久久久高潮| 欧美电影打屁股sp| 韩国女主播一区| 免费在线日韩av| 99国内精品久久| 亚洲一区二区三| 国内精品久久久久久| 久久精品欧洲| 新狼窝色av性久久久久久| 国产精品a久久久久久| 久久婷婷丁香| 亚洲一区二区免费在线| 国产精品入口尤物| 久久久夜色精品亚洲| 在线中文字幕不卡| 亚洲一区二区精品在线| 欧美黑人在线播放| 亚洲欧美日韩一区| 国产日韩视频| 欧美日韩在线播放| 欧美黄色网络| 亚洲一区制服诱惑| 亚洲免费观看高清完整版在线观看| 亚洲午夜久久久久久久久电影院 | 亚洲第一精品夜夜躁人人爽| 欧美日韩国产首页在线观看| 久久精品国产一区二区三| 在线亚洲免费| 蜜臀99久久精品久久久久久软件| 亚洲私人影院在线观看| 亚洲国产精品尤物yw在线观看| 国产精品一区二区男女羞羞无遮挡| 另类尿喷潮videofree| 亚洲午夜影视影院在线观看| 久久精品国产清自在天天线| 国产精品狼人久久影院观看方式| 国产精品久久久久秋霞鲁丝| 国产日韩精品视频一区| 欧美日韩在线综合| 欧美精品xxxxbbbb| 六月婷婷一区| 欧美日韩精品二区| 久久婷婷国产麻豆91天堂| 亚洲视频www| 亚洲一区二区av电影| 亚洲私人影院| 一本大道久久精品懂色aⅴ| 亚洲精品乱码久久久久久蜜桃91| 久久频这里精品99香蕉| 久久久水蜜桃av免费网站| 久久欧美中文字幕| 亚洲欧美在线aaa| 日韩亚洲精品在线| aa级大片欧美| 久久不射2019中文字幕| 欧美亚洲一区二区在线| 亚洲欧美日韩国产| 久久精品视频免费播放| 在线性视频日韩欧美| 亚洲欧美日韩一区在线| 久久夜精品va视频免费观看| 欧美日韩国产片| 欧美日韩三区四区| 精品二区视频| 亚洲日本成人网| 亚洲欧美日韩久久精品 | aa国产精品| 久久精精品视频| 免费一级欧美片在线观看| 欧美激情视频网站| 国产一区二区三区四区三区四| 尤物yw午夜国产精品视频明星| 欧美日韩三级视频|