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

cyt
發(fā)現(xiàn)原來(lái)已經(jīng)有兩個(gè)多月沒有寫blog了。近來(lái)工作都很忙,回到家都懶懶的不想動(dòng)。雖然工作上做了很多有趣的東西,但畢竟有版權(quán)保護(hù),在公司做的工作不能直接寫在blog上,也要抽些時(shí)間整理一下才能放上來(lái)。
??? 今天在 www.codeproject.com 上又發(fā)現(xiàn)比較好玩的東西:http://www.codeproject.com/cpp/acfdelegate.asp
或者去 http://acfproj.sourceforge.net/.

??? 作者甚是好耐心開發(fā)了一套和C#用法差不多的C++庫(kù)。當(dāng)然這里只是著重討論他的Delegate實(shí)現(xiàn)。其實(shí)Delegate也不是什么新技術(shù),正如下文有人提出的boost.singal (http://www.boost.org/doc/html/signals.html)、另外還有:

Delegate - Extended Callback Library????http://callbackext.berlios.de
Libsigc++?????????????????? http://libsigc.sourceforge.net
libSigCX(對(duì)libSigC++的擴(kuò)展) http://libsigx.sourceforge.net
sigslot??????????????????????? http://sigslot.sourceforge.net/
slotsig??????????????????????? http://slotsig.sourceforge.net/
????????????? 這個(gè)和上面的sigslot不是同一個(gè)東西,作者起的名字……一點(diǎn)新意都沒有,而且作者還提供了一個(gè)性能比較的benchmark,比較了qt、boost、libsigc++和自己,結(jié)果可以看這里:http://slotsig.sourceforge.net/doc/benchmarks.html
作者還說:The sigslot library has not been benchmarked, because it provides too less features than the others。當(dāng)然Qt用的是完全另外一套東西,通過預(yù)編譯實(shí)現(xiàn)的signal / slot,個(gè)人覺得完全沒有可比性,當(dāng)然Qt的實(shí)現(xiàn)方法也是我個(gè)人所討厭的,非要多一個(gè)預(yù)編譯器出來(lái),開發(fā)時(shí)候極為不爽。

??? 找回以前的代碼,我在2002年的時(shí)候原來(lái)也已經(jīng)實(shí)現(xiàn)過一個(gè)signal / slot,不過在slotsig作者眼中也是provides too less features。不過當(dāng)然是自己夠用就行了。之所以要“重復(fù)開發(fā)”,原因之一是以上的很多l(xiāng)ib不支持VC6,當(dāng)時(shí)我還在用破破爛爛的VC6;一方面我也不愿意自己的project里面塞一大堆lib,特別是boost的,龐大的嚇人;一方面也就是自己能力的鍛煉;還有一方面就是發(fā)現(xiàn)有些lib里面的實(shí)現(xiàn)用了些trick(例如用byte array保存指針),這也是個(gè)人不喜歡的東西。

??? 其實(shí)實(shí)現(xiàn)的原理很簡(jiǎn)單,先以一個(gè)簡(jiǎn)單的例子說明:
假設(shè)需要處理?? int??? f(int a);的singl / slot,如果單是函數(shù)指針,那就太簡(jiǎn)單了,slot就是函數(shù)指針,singal就是函數(shù)指針的數(shù)組。但現(xiàn)在還要加上對(duì)象的成員函數(shù),于是就會(huì)想到把這兩種東西合并起來(lái),但從外面看有相同的接口。其實(shí)function object就是這樣一種東西,不過function object只能在編譯時(shí)期實(shí)現(xiàn)普通函數(shù)和成員函數(shù)接口統(tǒng)一,但現(xiàn)在需要在運(yùn)行時(shí)期,很自然就會(huì)想到了虛函數(shù):
struct?slot1base
?? { virtual int fun(int a) = 0; };

typedef? SmartPotint?? slot1;

struct?singal1
{
??? int emit(int a) {??? /*?call each slot in m_listSlot?*/ }
??? void?connect( slot1 s) { m_listSlot.push_back(s); }

protected:
??? std::list?? m_listSlot;
};
其中SmartPoint就是帶引用計(jì)數(shù)的智能指針,很多實(shí)現(xiàn)的庫(kù),隨便選一個(gè)吧。
很明顯,我們現(xiàn)在就是需要一個(gè)singal1,然后往它里面的m_listSlot里面不斷放slot1base的子類?,F(xiàn)在要做的事情,就是要把不同的形如 int f(int)樣式的函數(shù)調(diào)用(包括普通函數(shù)和成員函數(shù))統(tǒng)統(tǒng)轉(zhuǎn)換為slot1base的子類。于是就有很多子類出來(lái)了:

struct slot1func : public slot1base
{
?typedef int (* func)(int);
?
?slot1func(func p) : m_func(p) {}
?virtual int fun(int a) { return m_func(a); }
private:
?func?m_func;
};

template
struct slot1objfunc : public slot1base
{
?typedef?int (obj::*func)(int);
?
?slot1objfunc(obj * p, func pF) : m_obj(p),m_pfunc(pF) {}
?virtual int fun(int a) { return (m_obj->*m_func)(a); }
private:
?obj?*?m_obj;
?func?m_pfunc;
};

其實(shí)除了這兩種以外,還可以擴(kuò)展出更多的子類,例如能自動(dòng)進(jìn)行函數(shù)參數(shù)的類型轉(zhuǎn)換的子類:
struct slot1func_for_short : public slot1base
{
?typedef?short (* func)(short);
?
?slot1func_for_short(func p) : m_func(p) {}
?virtual int fun(int a) { return m_func(a); }
private:
?func?m_func;
};
當(dāng)然可以抽象為template
template
struct slot1func_for_other : public slot1base
{
?typedef?R2 (* func)(A2);
?
?slot1func_for_other(func p) : m_func(p) {}
?virtual int fun(int a) { return m_func(a); }
private:
?func?m_func;
};
同樣還應(yīng)該有for object function的版本……
除了這些,還可以有更多的,例如處理object的const函數(shù)的;處理本來(lái)沒有返回值,每次需要虛擬一個(gè)返回值的函數(shù);參數(shù)個(gè)數(shù)不一致,需要另外bind參數(shù)的……

現(xiàn)在有了很多子類以后,我們當(dāng)然不希望要記著這么多子類的名稱,希望使用的時(shí)候只通過同一個(gè)接口就可以生成我們所需要的slot1,這時(shí)候就是經(jīng)典的template function出場(chǎng)了:
slot1?slot(int (*func)(int))
?{ return slot1( new slot1func(func) ); }
template
?slot2?slot(obj * p, int (obj::*func)(int) )
??{ return slot1( new slot1objfunc(p,func) ); }
template
?slot2?slot( R2 (*func)(A2) )
??{ return slot1( new slot1func_for_other(func) ); }

應(yīng)用的時(shí)候就可以:
int??? func1(int a) { ..... }
struct MyObj {??? int func2(int a) { .... } };

MyObj???? obj;

signal1????? onButtonClick;
onButtonClick.connect( slot( func1) );
onButtonClick.connect( slot( *obj, func2) );
return onButtonClick.emit( 100 );

原理很簡(jiǎn)單吧,但這個(gè)只是int func(int)格式的slot1,如果參數(shù)不是int,返回值不是int呢?簡(jiǎn)單,把上面的東西變成模版就行了。
template
struct?slot1base
?? { virtual?R fun(A1 a) = 0; };

template
struct slot1 : public? SmartPotint >?? {}

template
struct?singal1
{
????R emit(A a) {??? /*?call each slot in m_listSlot?*/ }
??? void?connect( slot1 s) { m_listSlot.push_back(s); }

protected:
??? std::list >?? m_listSlot;
};

……后面的子類也作相應(yīng)的處理。

原理是簡(jiǎn)單,不過要做一個(gè)完整的機(jī)制還要考慮更多的東西:
1、singal 和slot之間一般是“多對(duì)多”的關(guān)系,所以應(yīng)該slot里面也有singal的列表,以方便雙向查找。
2、多線程下的重入問題,如何加上鎖,是需要仔細(xì)考慮的。
3、當(dāng)一個(gè)singal里面包含多個(gè)slot的時(shí)候,那個(gè)返回值的處理,這個(gè)真的是多種多樣了:
???? 只要其中一個(gè)的返回值;所有返回值記錄在數(shù)組里面;當(dāng)其中一個(gè)返回值是特定值時(shí)候不繼續(xù)后面的slot……
???? 所以一般都會(huì)在singal1的模版參數(shù)中增加一個(gè)TMarshal的類來(lái)處理返回值:
???? template
???? struct singal1
???? {
???????? R emit(A1 a)
???????? {
??????????? typeMarsh?marsh;
??????????? /* for each item in m_listSlot*/
??????????? {
???????????????? if (! marsh.toContinue( (*it)->fun(a)))
????????????????????? break;
??????????? }
??????????? return marsh.value();
???????? }
??? };
?而一個(gè)簡(jiǎn)單TMarshal可以是這樣:
?template
??class TMarshal
??{
??public:
???TMarshal(void) : m_saveValue() {}
???static typeReturn?defaultValue(void) { return typeReturn(); }
???typeReturn?value(void) { return m_saveValue; }
???bool?toContinue(const typeReturn & val)
????{?m_saveValue = val;?return true;?}
??protected:
???typeReturn?m_saveValue;
??};
4、現(xiàn)在只是討論了一個(gè)參數(shù)的情況,多個(gè)參數(shù)的呢?好辦,copy/paste一個(gè)參數(shù)的,加上多個(gè)參數(shù)就是了,例如:
?template
??struct slot2base
???{? virtual R fun(A1 a1, A2 a2) = 0; };
?不過的確是很煩人的工作,于是很多l(xiāng)ib都是通過宏來(lái)實(shí)現(xiàn),例如:
?一個(gè) signalslot.imp的文件里面:
?template
??struct?SLOTBASENAME
???{?virtual R fun(FUNC_ARGS) = 0; };
?……
?而singalslot.h里面就定義:
?#define TEMPLATE_ARGS?typename A1
?#define FUNC_ARGS??A1 a1
?#define SLOTBASENAME?slot1base
?#include "signalslot.imp"
?
?#define TEMPLATE_ARGS?typename A1,typename A2
?#define FUNC_ARGS??A1 a1, A2 a2
?#define SLOTBASENAME?slot2base
?#include "signalslot.imp"
?……
?
?更有甚者,直接用perl來(lái)生成.h文件……
5、需要更多的接口,方便使用,例如slot的查找、刪除、比較之類的。

posted on 2005-10-08 14:50 cyt 閱讀(5433) 評(píng)論(2)  編輯 收藏 引用
Comments
  • # re: 我自己的signal / slot實(shí)現(xiàn)
    joyfire
    Posted @ 2005-11-26 00:24
    引用了這篇文章,可是找補(bǔ)到trackback:(  回復(fù)  更多評(píng)論   
  • # re: 我自己的signal / slot實(shí)現(xiàn)
    你好!
    Posted @ 2007-06-15 09:02
    你好, 看了你的文章感覺你好厲害得說!
    我不是專門研究程序的人,可現(xiàn)在我有點(diǎn)小困難,你肯定知道怎么解決
    你的文章里說:
    而singalslot.h里面就定義:
    #define TEMPLATE_ARGS typename A1
    #define FUNC_ARGS A1 a1
    #define SLOTBASENAME slot1base
    #include "signalslot.imp"

    #define TEMPLATE_ARGS typename A1,typename A2
    #define FUNC_ARGS A1 a1, A2 a2
    #define SLOTBASENAME slot2base
    #include "signalslot.imp"
    ……
    我運(yùn)行程序時(shí)候就缺少這個(gè)文件,一直在尋找這個(gè)頭文件,你能幫忙寫給我嗎?
    我的QQ346183499,全天再線
    謝謝了!  回復(fù)  更多評(píng)論   

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲日本视频| 精品动漫3d一区二区三区免费版 | 欧美精品三级| 亚洲日本中文字幕| 蘑菇福利视频一区播放| 欧美不卡视频一区发布| 亚洲精品一二区| aa级大片欧美三级| 国产精品视频xxxx| 久久成人免费视频| 日韩午夜三级在线| 免费成人性网站| 久久国产精品久久久久久久久久 | 亚洲三级免费| 在线亚洲伦理| 亚洲高清在线观看| 欧美呦呦网站| 亚洲天天影视| 国产色综合久久| 欧美性色aⅴ视频一区日韩精品| 久久精品夜色噜噜亚洲aⅴ| 亚洲国产一区二区三区高清| 久久激情综合网| 欧美高清hd18日本| 蜜桃av一区二区在线观看| 亚洲国产一区二区三区a毛片| 一区二区三区日韩精品视频| 99国内精品久久| 亚洲国产免费| 欧美一级久久久| 亚洲欧美日韩视频一区| 一区二区日韩欧美| 亚洲丁香婷深爱综合| 国产精品亚洲精品| 伊人久久大香线蕉av超碰演员| 国产精品视频免费| 亚洲黑丝在线| 亚洲国产你懂的| 性欧美在线看片a免费观看| 香蕉久久夜色精品国产| 亚洲国产成人在线播放| 久久gogo国模裸体人体| 久久久99精品免费观看不卡| 欧美午夜精品久久久久久人妖 | 99国产精品久久久久老师| 亚洲伦伦在线| 亚洲一区免费观看| 亚洲欧美激情视频| 午夜欧美不卡精品aaaaa| 久久经典综合| 一区二区三区国产精品| 欧美日本免费| 国产日韩1区| 亚洲国产成人tv| 亚洲精品日韩在线| 免费一级欧美在线大片| 欧美在线视频免费播放| 国产午夜一区二区三区| 欧美亚洲免费在线| 亚洲欧美中文在线视频| 国产精品推荐精品| 性欧美超级视频| 欧美影院成人| 永久久久久久| 欧美不卡激情三级在线观看| 久久综合色天天久久综合图片| 欧美成人精品不卡视频在线观看| 欧美精品亚洲精品| 99综合电影在线视频| 亚洲狼人精品一区二区三区| 亚洲欧美三级在线| 国产免费观看久久| 亚洲欧洲另类| 午夜精彩视频在线观看不卡 | 中文有码久久| 一区二区三区久久久| 国产免费成人在线视频| 免播放器亚洲一区| 欧美精品在线视频观看| 亚洲欧美日韩国产综合精品二区 | 国产精品成人观看视频免费 | 亚洲免费在线精品一区| 亚洲欧美在线aaa| 国产一区视频在线观看免费| 夜夜嗨av一区二区三区免费区| 日韩亚洲成人av在线| 国产亚洲欧美一区| 一区二区日本视频| 久久一区二区三区四区| 亚洲精品免费网站| 国产精品三级久久久久久电影| 久久国产精品久久久久久电车| 裸体歌舞表演一区二区| 国产区在线观看成人精品| 农村妇女精品| 国产精品啊啊啊| 欧美mv日韩mv国产网站app| 欧美日韩日本国产亚洲在线 | 一区免费观看视频| 亚洲精品在线观| 国内外成人在线| 亚洲欧美日韩综合aⅴ视频| 欧美自拍偷拍午夜视频| 一二美女精品欧洲| 久久人人九九| 136国产福利精品导航网址| 久久国产欧美日韩精品| 欧美风情在线| 日韩视频一区二区三区在线播放免费观看| 一本大道久久精品懂色aⅴ| 黄网动漫久久久| 亚洲夜晚福利在线观看| 欧美日韩视频免费播放| 久久亚洲精选| 国产精品美女久久| 欧美一区二区三区精品| 欧美福利小视频| 久久综合影视| 久久精品国产99| 午夜免费电影一区在线观看| 欧美久久婷婷综合色| 欧美ab在线视频| 狠狠色狠狠色综合日日tαg| 亚洲女女做受ⅹxx高潮| 国产亚洲女人久久久久毛片| 亚洲精品女av网站| 一区二区在线不卡| 欧美一级片在线播放| 亚洲欧美国内爽妇网| 欧美视频精品一区| 久久精品久久99精品久久| 欧美视频一区二| 亚洲免费观看高清在线观看| 亚洲日本欧美| 欧美大色视频| 最新日韩在线视频| 国产欧美在线视频| 亚洲午夜一区二区三区| 亚洲淫片在线视频| 欧美视频网址| 亚洲男人的天堂在线观看| 欧美一区二区三区免费大片| 国产日产精品一区二区三区四区的观看方式 | 一本一本久久a久久精品牛牛影视| 久久人体大胆视频| 国产精品永久入口久久久| 性伦欧美刺激片在线观看| 国产精品高清一区二区三区| 日韩视频在线观看免费| 亚洲一区日本| 国产伦精品一区二区三区视频孕妇 | 国产一区二区毛片| 久久av资源网站| 欧美高清影院| 亚洲天堂av电影| 国产精品美女一区二区在线观看| 亚洲欧美日韩在线不卡| 牛牛国产精品| 亚洲一二三区在线| 久久爱www久久做| 嫩模写真一区二区三区三州| 亚洲美女在线视频| 国产精品二区在线| 久久不射中文字幕| 亚洲人成人77777线观看| 亚洲欧美视频在线观看视频| 国内成人精品视频| 欧美激情视频一区二区三区在线播放 | 久久亚洲影院| 亚洲国产精品免费| 亚洲综合不卡| 一区在线视频| 欧美午夜精品久久久久久超碰| 欧美一区二区视频观看视频| 亚洲电影天堂av| 欧美伊久线香蕉线新在线| 亚洲黄色小视频| 国产精品丝袜白浆摸在线| 蜜桃av一区| 午夜精品久久久久久久白皮肤| 欧美国产日韩一区二区三区| 国产日韩视频| 欧美激情影音先锋| 久久国产66| 中文在线资源观看网站视频免费不卡 | 久热精品视频| 亚洲综合色激情五月| 亚洲韩国日本中文字幕| 国产精品综合不卡av| 欧美a级片一区| 久久成人综合视频| 午夜国产精品视频| 夜夜精品视频| 亚洲精品国产精品乱码不99| 麻豆freexxxx性91精品| 亚洲欧美日韩国产精品| 在线综合视频| 亚洲美女视频网| 亚洲人成人77777线观看| 极品少妇一区二区三区精品视频|