日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++中实现回调机制的几种方式

發布時間:2025/6/15 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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更小更靈活。?

你更傾向于用哪種方式來實現回調?

總結

以上是生活随笔為你收集整理的C++中实现回调机制的几种方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产欧美久久久 | 亚洲图色av | 婷婷激情丁香 | 嫩草视频免费观看 | 手机在线看黄色 | 乱淫67194 | 国产xxxx在线观看 | 中文字幕一区在线播放 | 亚洲91精品 | 免费看成人啪啪 | 国产高清av | 白白色在线观看 | 亚洲av人人夜夜澡人人 | 欧美大片在线观看 | 日日噜噜夜夜狠狠久久丁香五月 | 午夜xxx | 大黑人交交护士xxxxhd | 伊人激情影院 | 中文字幕一区二区三区久久久 | aaa在线| 蜜臀99久久精品久久久久久软件 | 奇米影视在线观看 | 欧美日韩高清一区二区 国产亚洲免费看 | 在线亚洲观看 | 九九视屏| 91免费视频观看 | 久久久久久久久久网站 | 伊人免费在线观看高清版 | 美痴女~美人上司北岛玲 | 欧美视频在线一区二区三区 | 欧美一区二区三区免费观看 | 落日余晖图片 | 老妇高潮潮喷到猛进猛出 | 天天摸夜夜添 | 亚洲精品www.| 日本色悠悠 | 国产夫妻自拍av | 激情婷婷| 成人午夜免费在线 | 一级黄色片网站 | 免费看黄网站在线 | 人妻一区二区三 | 国内自拍在线 | 欧美国产精品一区二区三区 | 草莓视频在线观看18 | 日日碰狠狠躁久久躁蜜桃 | 日本国产一区二区 | 国产美女在线精品 | 欧美精品色呦呦 | 日本啪啪网 | missav | 免费高清av在线看 | 丰满人妻一区二区三区性色 | 夜夜骚av一区二区三区 | 男人天堂你懂的 | 久久久久人妻一区精品色欧美 | 在线视频1卡二卡三卡 | 亚洲乱码国产乱码精品天美传媒 | 床戏高潮做进去大尺度视频网站 | 在线色播 | 国产性猛交╳xxx乱大交一区 | 欧美日韩高清 | 超碰av免费 | 日一区二区 | 国产三级全黄 | 香蕉视频网址 | 国产免费一区二区三区 | 一级做a爱片久久毛片 | 波多野结衣潜藏淫欲 | 怡红院毛片 | 国产精品宾馆在线精品酒店 | 风韵少妇性饥渴推油按摩视频 | 久草剧场 | 日韩高清免费观看 | 欧美精品一区二区三区蜜臀 | 美女av在线免费观看 | 日本高清xxx| 日本少妇激情 | 夏目彩春娇喘呻吟高潮迭起 | 糖心av| 日本少妇高潮喷水xxxxxxx | 国产视色 | 青草视频污 | 亚洲专区中文字幕 | 乱lun合集小可的奶水 | 午夜一级黄色片 | 国产精品麻豆一区二区三区 | 亚洲私拍| 精品中文字幕在线播放 | 国产精品人人做人人爽 | 亚洲av无码不卡 | 孕妇爱爱视频 | 日本少妇xxxxxx| 粗大的内捧猛烈进出视频 | 亚洲欧美日本国产 | 日韩欧美中文字幕精品 | 警察高h荡肉呻吟男男 | 果冻传媒18禁免费视频 | 亚洲 欧美 日韩系列 | 亚洲精品国产视频 |