• <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>

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            C++回調(diào)函數(shù)(callback)與仿函數(shù)(functor)的異同

            C++回調(diào)函數(shù)(callback)與仿函數(shù)(functor)的異同

            許式偉 (版權(quán)聲明)
            2007-3-3

            回調(diào)函數(shù)(callback)與仿函數(shù)(functor)很多時(shí)候從用途上來(lái)看很相似,以致于我們經(jīng)常將它們相提并論。例如:

            inline bool compare(int a, int b)
            {
               
            return a > b;
            }
             
            struct comparer {
              
            bool operator()(int a, int b) const {
                 
            return a > b;
              }
            };
             
            void main()
            {
               std::vector
            <int> vec, vec2;
               std::sort(vec.begin(), vec.end(), compare);
               std::sort(vec2.begin(), vec2.end(), comparer());
            }

            仿函數(shù)(functor)之所以稱為仿函數(shù),是因?yàn)檫@是一種利用某些類對(duì)象支持operator()的特性,來(lái)達(dá)到模擬函數(shù)調(diào)用效果的技術(shù)。

            如果這里vec, vec2這兩個(gè)vector的內(nèi)容一樣,那么從執(zhí)行結(jié)果看,使用回調(diào)函數(shù)compare與使用仿函數(shù)comparer是一樣的。

            那么,我們應(yīng)該用回調(diào),還是用仿函數(shù)?

            很多人都說(shuō)用仿函數(shù)吧,回調(diào)函數(shù)是丑陋的,代碼不太象C++風(fēng)格。

            但其實(shí)問(wèn)題的本質(zhì)不是在代碼風(fēng)格上,仿函數(shù)與回調(diào)函數(shù)各有利弊,不能一概而論。

            仿函數(shù)(functor)的優(yōu)點(diǎn)

            我的建議是,如果可以用仿函數(shù)實(shí)現(xiàn),那么你應(yīng)該用仿函數(shù),而不要用回調(diào)。原因在于: 

            • 仿函數(shù)可以不帶痕跡地傳遞上下文參數(shù)。而回調(diào)技術(shù)通常使用一個(gè)額外的void*參數(shù)傳遞。這也是多數(shù)人認(rèn)為回調(diào)技術(shù)丑陋的原因。
            • 更好的性能。

            仿函數(shù)技術(shù)可以獲得更好的性能,這點(diǎn)直觀來(lái)講比較難以理解。你可能說(shuō),回調(diào)函數(shù)申明為inline了,怎么會(huì)性能比仿函數(shù)差?我們這里來(lái)分析下。我們假設(shè)某個(gè)函數(shù)func(例如上面的std::sort)調(diào)用中傳遞了一個(gè)回調(diào)函數(shù)(如上面的compare),那么可以分為兩種情況:

            • func是內(nèi)聯(lián)函數(shù),并且比較簡(jiǎn)單,func調(diào)用最終被展開了,那么其中對(duì)回調(diào)函數(shù)的調(diào)用也成為一普通函數(shù)調(diào)用(而不是通過(guò)函數(shù)指針的間接調(diào)用),并且如果這個(gè)回調(diào)函數(shù)如果簡(jiǎn)單,那么也可能同時(shí)被展開。在這種情形下,回調(diào)函數(shù)與仿函數(shù)性能相同。
            • func是非內(nèi)聯(lián)函數(shù),或者比較復(fù)雜而無(wú)法展開(例如上面的std::sort,我們知道它是快速排序,函數(shù)因?yàn)榇嬖谶f歸而無(wú)法展開)。此時(shí)回調(diào)函數(shù)作為一個(gè)函數(shù)指針傳入,其代碼亦無(wú)法展開。而仿函數(shù)則不同。雖然func本身復(fù)雜不能展開,但是func函數(shù)中對(duì)仿函數(shù)的調(diào)用是編譯器編譯期間就可以確定并進(jìn)行inline展開的。因此在這種情形下,仿函數(shù)比之于回調(diào)函數(shù),有著更好的性能。并且,這種性能優(yōu)勢(shì)有時(shí)是一種無(wú)可比擬的優(yōu)勢(shì)(對(duì)于std::sort就是如此,因?yàn)樵乇容^的次數(shù)非常巨大,是否可以進(jìn)行內(nèi)聯(lián)展開導(dǎo)致了一種雪崩效應(yīng))。

            仿函數(shù)(functor)不能做的?

            話又說(shuō)回來(lái)了,仿函數(shù)并不能完全取代回調(diào)函數(shù)所有的應(yīng)用場(chǎng)合。例如,我在std::AutoFreeAlloc中使用了回調(diào)函數(shù),而不是仿函數(shù),這是因?yàn)锳utoFreeAlloc要容納異質(zhì)的析構(gòu)函數(shù),而不是只支持某一種類的析構(gòu)。這和模板(template)不能處理在同一個(gè)容器中支持異質(zhì)類型,是一個(gè)道理。

             

            Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1519828

            posted on 2007-09-03 15:27 楊粼波 閱讀(376) 評(píng)論(0)  編輯 收藏 引用


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


            亚洲国产精品久久久久久| 久久午夜综合久久| 久久精品国产精品亚洲毛片| 久久se精品一区二区| 久久精品国产2020| 久久久九九有精品国产| 久久久久亚洲AV片无码下载蜜桃| 亚洲国产成人精品久久久国产成人一区二区三区综 | 色综合久久88色综合天天 | 欧美精品福利视频一区二区三区久久久精品 | 久久福利资源国产精品999| 欧美激情精品久久久久久| 国产999精品久久久久久| 无码伊人66久久大杳蕉网站谷歌 | 99久久精品免费看国产一区二区三区 | 区亚洲欧美一级久久精品亚洲精品成人网久久久久| 日韩欧美亚洲综合久久影院Ds | 无遮挡粉嫩小泬久久久久久久| 日本精品久久久中文字幕| 欧美精品一区二区久久| 国内精品久久久久| 无码人妻久久一区二区三区| 久久精品国产亚洲7777| 久久亚洲国产成人精品性色| 亚洲精品综合久久| 久久国产精品二国产精品| 狠狠色噜噜狠狠狠狠狠色综合久久| 人妻精品久久久久中文字幕| 99久久国产免费福利| 久久精品成人免费看| 久久久无码精品亚洲日韩蜜臀浪潮 | 91精品国产91久久| 91精品国产综合久久四虎久久无码一级 | 伊人久久大香线蕉影院95| 99re久久精品国产首页2020| 欧美一区二区三区久久综| 亚洲日韩中文无码久久| 中文字幕日本人妻久久久免费 | 欧美伊人久久大香线蕉综合69| 久久99国产一区二区三区| 久久精品国产99久久久香蕉|