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

huaxiazhihuo

 

略說(shuō)成員函數(shù)指針及其模板的精簡(jiǎn)實(shí)現(xiàn)

    請(qǐng)容許先發(fā)一句牢騷,“這萬(wàn)惡的成員函數(shù)指針的丑陋語(yǔ)法!”,C中的函數(shù)指針的語(yǔ)法已經(jīng)夠難看的了,但相比之下,成員函數(shù)指針卻更加不堪入目,使用上又很不方便,很不人性化,簡(jiǎn)直是只能行走寸步。只可惜,函數(shù)指針的作用實(shí)在太大了,忽視不得。
    大家都知道,函數(shù)指針(或又叫回調(diào)函數(shù))是上層模塊和底層模塊進(jìn)行通信的最佳手段,上層通過(guò)提供函數(shù)指針給底層,以使得底層在適當(dāng)?shù)臅r(shí)候,可以調(diào)用執(zhí)行上層的代碼,C庫(kù)中的qsort足以說(shuō)明這種使用,qsort在排序時(shí),不知道如何比較兩個(gè)數(shù)組元素的大小,必須通過(guò)上層提供的大小比較函數(shù)來(lái)進(jìn)行比較。此外,操作系統(tǒng)提供的API中,有多少地方使用上了回調(diào)函數(shù)。假如沒(méi)有函數(shù)指針,這簡(jiǎn)直沒(méi)法想像,日子沒(méi)法過(guò)了。函數(shù)指針是實(shí)現(xiàn)模塊分層的不二法門(mén),當(dāng)然接口也可以,但是,用戶代碼必須繼承或者實(shí)現(xiàn)底層硬性規(guī)定無(wú)理取鬧的虛函數(shù),本來(lái)很輕量級(jí)的POD,再也不輕快了,實(shí)在頗不方便,不,簡(jiǎn)直很有點(diǎn)惡心。說(shuō)來(lái)說(shuō)去,還是函數(shù)指針好。
    既然,C中的回調(diào)函數(shù)這么重要,那么,可想而知,進(jìn)入C++中,整個(gè)世界到處都是CLASS,將回調(diào)函數(shù)這個(gè)概念推廣到CLASS上,也即是成員函數(shù)指針,將是多么迫切的事情。理論上,可以將成員函數(shù)指針視為函數(shù)指針的語(yǔ)法糖,只要規(guī)定函數(shù)指針的第一個(gè)參數(shù)為void* pThis,然后在函數(shù)指針的實(shí)現(xiàn)函數(shù)中,進(jìn)行類型轉(zhuǎn)換也能滿足使用,在很長(zhǎng)的一段時(shí)間里,因?yàn)檫@種方式的簡(jiǎn)單清晰,一直都用這種方式代替成員函數(shù)指針。但是,一遍又一遍地被迫編寫(xiě)重復(fù)代碼,特別是枯燥的類型轉(zhuǎn)換,任何人都無(wú)法忍受。因此,決定直面這個(gè)問(wèn)題。
    理論上,成員函數(shù)和普通函數(shù)一樣,在內(nèi)存中,都有自己的位置,只要有了地址信息,就可以通過(guò)指針來(lái)獲取,保存起來(lái),然后在未來(lái)的某個(gè)地方,通過(guò)這個(gè)指針來(lái)執(zhí)行函數(shù)中的代碼。差別之處,在于,調(diào)用成員函數(shù)前,要先將this推入ecx中,很久之前,成員函數(shù)指針確實(shí)和普通函數(shù)指針一樣簡(jiǎn)單,只是后來(lái),虛函數(shù)和多繼承出現(xiàn)之后,簡(jiǎn)單的指針信息再也承載不了成員函數(shù)的重量,從此之后,.......(忽略,請(qǐng)大家自行BAIDU)??傊珻++中,成員函數(shù)指針并非指針類型,理所當(dāng)然,也就不支持指針的大多數(shù)操作,比如,賦值NULL,或者類型轉(zhuǎn)換。因此,所有能夠讓函數(shù)指針大放異彩的種種手段,在這里,都用不上了,原本在C中光芒四射的好東西,到了C++中,竟然黯然失色,所有本該讓函數(shù)指針大顯身手的地方,大家都繞道而行。
    逼急了,也有嘗試突破,MFC的僅僅作了有限爭(zhēng)取的手段(為了這一點(diǎn)點(diǎn)好處,MFC可不知作了多大的努力),居然成為其消息映射的基石。但是,據(jù)說(shuō),MFC的成員函數(shù)指針的設(shè)計(jì)也非出于自愿,而是因?yàn)橄⑻啵瑢?shí)在沒(méi)法整成虛函數(shù)來(lái)處理,每個(gè)窗口類背負(fù)成千上萬(wàn)個(gè)函數(shù)的虛函數(shù)表,可不是省油的燈。為了努力地支持虛函數(shù)和多繼承,C++的編譯器不惜在成員函數(shù)指針的使用上設(shè)下種種阻攔,令人又氣又恨。而更加令人不解的是,C++橫行天下十幾年,函數(shù)指針?biāo)坪蹰L(zhǎng)期得不到重視,大師們都在面向?qū)ο笊咸剿?,很多本該成員函數(shù)指針發(fā)光發(fā)熱的地方,幾乎都退位給虛函數(shù)了,并美其名曰策略模式又或者是其他的什么模式,不過(guò)是換了一套更加難看的馬甲,卻又那么好聽(tīng)的名字,不,不好聽(tīng),只要聽(tīng)到模式兩字,就令人大倒胃口。所有大用特用模式的代碼,如果用非模式來(lái)實(shí)現(xiàn),其代碼量將少掉很多,而且還更具擴(kuò)展性,這是真的。先透露一下,正在構(gòu)思一文章,將深度介紹模式,專注于WHY,并且類比現(xiàn)實(shí),兼扯上WINDOWS、COM和MFC對(duì)模式的應(yīng)用,說(shuō)句良心話,如果只用接口來(lái)做設(shè)計(jì),模式絕對(duì)是好東西。只可惜,接口其實(shí)是SB。寫(xiě)底層代碼,如果要求用戶必須實(shí)現(xiàn)某些接口,又或者是繼承某些類,改寫(xiě)虛函數(shù),這種侵入式的設(shè)計(jì),實(shí)在無(wú)理取鬧之至。
    后來(lái),大伙兒也終于開(kāi)始重視成員函數(shù)指針,特別是C#的委托出現(xiàn)之后,網(wǎng)絡(luò)上更是充斥著各種成員函數(shù)指針的版本代碼,都可以很好地完成任務(wù)。特別是TR1又或者是BOOST中的function,功能相當(dāng)?shù)膹?qiáng)悍得令人非大吃一驚不可。只可惜,大多數(shù)情況下,用戶只想填飽肚子而已,但是BOOST或者其他的類庫(kù)卻硬要來(lái)一桌滿漢全席,這也罷了,但是,它還要用戶額外買(mǎi)單,并且還真不低呢,這就很讓人受不了啦。其實(shí),一般情況下,我們的要求不會(huì)太過(guò)分,僅僅想要針對(duì)普通的成員函數(shù)指針進(jìn)行回調(diào),它卻為此在其內(nèi)部new一個(gè)內(nèi)部類出來(lái),假如大規(guī)模使用,后果將不堪設(shè)想,其實(shí)也沒(méi)那么嚴(yán)重,完成是C++迷們的強(qiáng)迫癥。
    但是,說(shuō)真的,實(shí)在希望很精簡(jiǎn),不要生成不必要的虛函數(shù)表,不要模板生成不必要的函數(shù)(沒(méi)辦法內(nèi)聯(lián),有函數(shù)地址的那一種),只要求它如同對(duì)待C中的函數(shù)指針一樣,參數(shù)入棧和一個(gè)簡(jiǎn)單的函數(shù)調(diào)用的指令,外加將this推入ecx即可,就好像直接調(diào)用成員函數(shù)那樣就好了。好了,貢獻(xiàn)上代碼了,史上最輕量級(jí),精簡(jiǎn)無(wú)比的成員函數(shù)指針,功能也最弱了。對(duì)不起,代碼并不完整,實(shí)際的代碼,用上了宏,所謂的宏的圖靈完備。在下很懶,一向只介紹想法而已,只于具體的實(shí)現(xiàn)細(xì)節(jié)以及語(yǔ)法考究,竊以為,每個(gè)C++迷們應(yīng)該完全能夠勝任。俗話說(shuō),高手只要求創(chuàng)意就行了,本文詳細(xì)介紹算法并給出代碼,已經(jīng)落了下乘。
    這個(gè)實(shí)現(xiàn),不考慮多繼承,忽略了虛函數(shù),也不支持非成員函數(shù)(也可以用上,只是,要多做一點(diǎn)點(diǎn)手腳,以下將給出示例,而且,普通函數(shù)指針已經(jīng)完全可以勝任),只集中火力專注于普通成員函數(shù),畢竟,在下的運(yùn)用中,它占上了95%以上,所以才能如此的高效。單一職責(zé)?。?br />    此外,本文參考了《成員函數(shù)指針與高性能的C++委托》、《劉未鵬的BOOST源碼解析》、《C++設(shè)計(jì)新思維》,請(qǐng)自行GOOGLE。
template <class OutputClass, class InputClass>
union horrible_union{
    OutputClass 
out;
    InputClass 
in;
};

template 
<class OutputClass, class InputClass>
inline 
void union_cast(OutputClass& outconst InputClass input){
    horrible_union
<OutputClass, InputClass> u;
    typedef 
int ERROR_CantUseHorrible_cast[sizeof(InputClass)==sizeof(u) 
        
&& sizeof(InputClass)==sizeof(OutputClass) ? 1 : -1];
    u.
in = input;
    
out = u.out;
}

template
<typename FuncSignature>class TMemFn;
class CCallbackObject{};

template
<typename R>
class TMemFn<R ()>
{
public:
    typedef R ReturnType;
    ReturnType 
operator()() const{return (pThis->*func)();}

    template
<typename _Ty>
    
void Bind(_Ty* pObj, R(_Ty::*proc)())
    {
        union_cast(pThis, pObj);
        union_cast(func, proc);
    }

public:
    typedef ReturnType (CCallbackObject::
*FuncType)();
    FuncType func;
    CCallbackObject
* pThis;
};

template
<typename R, typename P1>
class TMemFn<R (P1)>
{
public:
    typedef R ReturnType;
    typedef P1 Param1Type;

    ReturnType 
operator()(Param1Type param1) const{return (pThis->*func)(param1);}

    template
<typename _Ty>
    
void Bind(_Ty* pObj, ReturnType(_Ty::*proc)(Param1Type))
    {
        union_cast(pThis, pObj);
        union_cast(func, proc);
    }

public:
    typedef ReturnType (CCallbackObject::
*FuncType)(Param1Type);
    FuncType func;
    CCallbackObject
* pThis;
};

template
<typename R, typename _Ty>
TMemFn
<R ()> MakeMF(_Ty* pThis, R(_Ty::*proc)())
{
    TMemFn
<R ()> res; res.Bind(pThis, proc);
    
return res;
}

template
<typename R, typename _Ty, typename P1>
TMemFn
<R (P1)> MakeMF(_Ty* pThis, R(_Ty::*proc)(P1))
{
    TMemFn
<R (P1)> res;res.Bind(pThis, proc);
    
return res;
}

int Test(int a)
{
    printf(
"Hello World %d\n", a);
    
return a;
}

int _tmain(int argc, _TCHAR* argv[])
{
    
class _CTest
    {
    
public:
        
int CallTest(int a)
        {
            
return Test(a);
        }
    };
    TMemFn
<int (int)> aTest = MakeMF((_CTest*)NULL, &_CTest::CallTest);
    aTest(
80);
    
return 0;
}

posted on 2012-11-16 10:46 華夏之火 閱讀(2965) 評(píng)論(4)  編輯 收藏 引用 所屬分類: c++技術(shù)探討

評(píng)論

# re: 略說(shuō)成員函數(shù)指針及其模板的精簡(jiǎn)實(shí)現(xiàn) 2012-11-16 17:32 Richard Wei

還是直接用C++ 11中的function吧  回復(fù)  更多評(píng)論   

# re: 略說(shuō)成員函數(shù)指針及其模板的精簡(jiǎn)實(shí)現(xiàn) 2012-11-16 17:55 華夏之火

@Richard Wei
直接用function,會(huì)有心理負(fù)擔(dān),雖然沒(méi)有必要  回復(fù)  更多評(píng)論   

# re: 略說(shuō)成員函數(shù)指針及其模板的精簡(jiǎn)實(shí)現(xiàn) 2012-11-22 07:39 fzy

其實(shí)一切源于

typedef TRET (TClass::*P_METHOD)( TPARAM... );
typedef TRET (__cdecl *P_FUNC_CDECL)( TPARAM... );
typedef TRET (__stdcall * P_FUNC_STDCALL)( TPARAM... );
typedef TRET (__fastcall * P_FUNC_FASTCALL)( TPARAM... );

剩下的就是解決
TRET 和 TPARAM... 類型以及 P_METHOD/P_FUNC_XXXXX 的打包問(wèn)題。

中間比較繁瑣的是 TRET 的void 特例,以及TPARAM...的傳參類型。

在某些特定環(huán)境下,還需要考慮TPARAM...的存儲(chǔ)類型。

不過(guò)c++的template有特化來(lái)實(shí)現(xiàn)這些東西,所以最后都?xì)w結(jié)到工作量了。  回復(fù)  更多評(píng)論   

# re: 略說(shuō)成員函數(shù)指針及其模板的精簡(jiǎn)實(shí)現(xiàn) 2012-11-22 09:27 華夏之火

@fzy
有必要支持那么多嗎,只要typedef TRET (TClass::*P_METHOD)( TPARAM... )這一個(gè)就行了,void 確實(shí)比較特別  回復(fù)  更多評(píng)論   

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

留言簿(6)

隨筆分類

隨筆檔案

搜索

積分與排名

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美在线观看一二区| 欧美国产精品v| 亚洲成人在线视频播放| 国产视频久久久久| 国产亚洲一区精品| 伊伊综合在线| 亚洲乱码久久| 亚洲天堂男人| 久久精品官网| 亚洲第一在线视频| 亚洲狼人综合| 亚洲色诱最新| 久久精品99无色码中文字幕| 裸体歌舞表演一区二区| 欧美日韩精品免费在线观看视频| 国产精品高清网站| 亚洲国产日韩在线| 日韩视频在线免费观看| 亚洲午夜精品久久久久久浪潮 | 国产欧美一区二区精品婷婷| 国产自产高清不卡| 亚洲精品一区在线| 午夜视频在线观看一区二区三区 | 国产综合色在线| 亚洲精品国产品国语在线app| 国产精品99久久久久久有的能看 | 国产一级精品aaaaa看| 亚洲精品一区二区网址| 欧美一级专区免费大片| 亚洲国产一区二区三区高清| 亚洲亚洲精品三区日韩精品在线视频| 久久国产精品一区二区三区| 欧美日韩另类综合| 在线欧美影院| 久久人人精品| 亚洲在线黄色| 欧美网站在线观看| 亚洲人成高清| 老司机凹凸av亚洲导航| 精品成人一区二区| 午夜日韩电影| 日韩视频免费观看高清完整版| 欧美一区二视频| 国产精品夜夜嗨| 亚洲午夜免费视频| 亚洲茄子视频| 欧美激情精品久久久久久蜜臀 | 欧美激情一区二区三区在线| 韩国精品在线观看| 欧美亚洲一区三区| 一区二区三区三区在线| 欧美激情第二页| 亚洲国产日韩欧美在线99 | 欧美日本中文字幕| 亚洲精品日产精品乱码不卡| 巨乳诱惑日韩免费av| 亚洲欧美精品| 国产精品视频一区二区高潮| 亚洲一区图片| 一区电影在线观看| 国产精品久久久久久久久免费| 亚洲精品乱码久久久久久按摩观| 欧美91福利在线观看| 宅男噜噜噜66一区二区66| 在线日韩精品视频| 久久免费99精品久久久久久| 性欧美xxxx视频在线观看| 国产精品免费久久久久久| 亚洲在线1234| 午夜视频久久久久久| 国产一区 二区 三区一级| 久久久久久91香蕉国产| 久久精品动漫| 亚洲伦理一区| 亚洲性视频网站| 韩日成人在线| 亚洲国产日韩在线一区模特| 欧美精品日韩www.p站| 亚洲一二三区精品| 亚洲制服av| 亚洲国产高清在线| 亚洲毛片在线看| 国产欧美一区二区在线观看| 久久一区二区三区超碰国产精品| 麻豆国产精品777777在线| aa成人免费视频| 亚洲视频一二区| 激情五月婷婷综合| 亚洲欧洲综合| 国产亚洲综合精品| 亚洲欧洲综合另类在线| 9l视频自拍蝌蚪9l视频成人 | 一区二区亚洲精品| 亚洲破处大片| 国产小视频国产精品| 亚洲福利免费| 国产女同一区二区| 亚洲国产91精品在线观看| 欧美色网一区二区| 玖玖视频精品| 国产精品日韩欧美综合| 欧美成人中文字幕在线| 国产精品视频观看| 亚洲国产专区校园欧美| 国产日韩欧美在线播放不卡| 亚洲精品国产品国语在线app| 国产亚洲日本欧美韩国| 亚洲免费福利视频| 亚洲福利视频二区| 午夜日韩av| 亚洲一区二区三区精品在线观看| 老牛国产精品一区的观看方式| 亚洲欧美经典视频| 欧美www视频| 久久久久久久波多野高潮日日| 欧美日韩调教| 亚洲韩国精品一区| 伊人男人综合视频网| 亚洲在线网站| 亚洲欧美日韩国产一区二区三区| 欧美成人午夜| 欧美国产精品中文字幕| 好看的亚洲午夜视频在线| 一区二区精品在线观看| 99riav1国产精品视频| 久久久夜夜夜| 久久婷婷色综合| 欧美精品久久久久久久免费观看| 国内精品久久久久久影视8| 一区二区免费看| 一本久道久久综合中文字幕 | 国产精品青草久久久久福利99| 亚洲福利专区| 亚洲电影观看| 久久久噜噜噜| 欧美高清影院| 亚洲国产视频一区| 你懂的网址国产 欧美| 裸体丰满少妇做受久久99精品| 国产性色一区二区| 午夜在线一区二区| 久久久无码精品亚洲日韩按摩| 国产女主播一区二区三区| 亚洲在线一区二区三区| 欧美一区二区三区视频在线| 国产精品高清免费在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 亚洲一区国产| 国产精品美女久久久| 亚洲一区二区三区免费观看| 欧美一区国产二区| 一区二区三区在线免费播放| 久久在线视频| 亚洲精品一区二区三区婷婷月| 一区二区三区精品国产| 国产精品一级二级三级| 久久精品99国产精品日本| 免费日韩成人| 在线亚洲自拍| 国产亚洲成av人片在线观看桃| 欧美中文在线免费| 欧美va亚洲va日韩∨a综合色| 亚洲精品欧美精品| 国产精品网站在线| 久久久久亚洲综合| 亚洲免费成人av电影| 久久久精品午夜少妇| 亚洲精品视频在线观看免费| 欧美丝袜一区二区三区| 午夜视频一区在线观看| 欧美国产极速在线| 午夜精品成人在线| 亚洲国产成人久久| 国产精品户外野外| 欧美成人黑人xx视频免费观看 | 欧美大片在线看| 亚洲综合精品自拍| 亚洲国产欧美另类丝袜| 久久国产精品亚洲va麻豆| 亚洲日本激情| 国语自产在线不卡| 国产精品成人观看视频国产奇米| 久久成人免费网| 夜夜嗨av一区二区三区四季av | 国产精品高潮久久| 免费久久99精品国产自| 亚洲欧美精品伊人久久| 亚洲青色在线| 欧美国产成人精品| 久久精品国产第一区二区三区| 亚洲精品一二三区| 亚洲一区在线直播| 久久夜精品va视频免费观看| 中国女人久久久| 欧美屁股在线| 99天天综合性| 最近看过的日韩成人| 中文在线资源观看网站视频免费不卡| 欧美一区二区三区啪啪| 一本久久综合亚洲鲁鲁|