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

            牽著老婆滿街逛

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

            C++回調函數(callback)與仿函數(functor)的異同

            C++回調函數(callback)與仿函數(functor)的異同

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

            回調函數(callback)與仿函數(functor)很多時候從用途上來看很相似,以致于我們經常將它們相提并論。例如:

            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());
            }

            仿函數(functor)之所以稱為仿函數,是因為這是一種利用某些類對象支持operator()的特性,來達到模擬函數調用效果的技術。

            如果這里vec, vec2這兩個vector的內容一樣,那么從執行結果看,使用回調函數compare與使用仿函數comparer是一樣的。

            那么,我們應該用回調,還是用仿函數?

            很多人都說用仿函數吧,回調函數是丑陋的,代碼不太象C++風格。

            但其實問題的本質不是在代碼風格上,仿函數與回調函數各有利弊,不能一概而論。

            仿函數(functor)的優點

            我的建議是,如果可以用仿函數實現,那么你應該用仿函數,而不要用回調。原因在于: 

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

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

            • func是內聯函數,并且比較簡單,func調用最終被展開了,那么其中對回調函數的調用也成為一普通函數調用(而不是通過函數指針的間接調用),并且如果這個回調函數如果簡單,那么也可能同時被展開。在這種情形下,回調函數與仿函數性能相同。
            • func是非內聯函數,或者比較復雜而無法展開(例如上面的std::sort,我們知道它是快速排序,函數因為存在遞歸而無法展開)。此時回調函數作為一個函數指針傳入,其代碼亦無法展開。而仿函數則不同。雖然func本身復雜不能展開,但是func函數中對仿函數的調用是編譯器編譯期間就可以確定并進行inline展開的。因此在這種情形下,仿函數比之于回調函數,有著更好的性能。并且,這種性能優勢有時是一種無可比擬的優勢(對于std::sort就是如此,因為元素比較的次數非常巨大,是否可以進行內聯展開導致了一種雪崩效應)。

            仿函數(functor)不能做的?

            話又說回來了,仿函數并不能完全取代回調函數所有的應用場合。例如,我在std::AutoFreeAlloc中使用了回調函數,而不是仿函數,這是因為AutoFreeAlloc要容納異質的析構函數,而不是只支持某一種類的析構。這和模板(template)不能處理在同一個容器中支持異質類型,是一個道理。

             

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

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

            国内精品久久久久影院网站| 亚洲v国产v天堂a无码久久| 99久久无码一区人妻a黑| 99国产欧美精品久久久蜜芽| 国产精品欧美久久久久天天影视| 四虎国产精品成人免费久久| 久久精品国产99国产精偷 | 国产精品欧美亚洲韩国日本久久 | 久久激情亚洲精品无码?V| 伊人久久无码中文字幕| 精品人妻伦一二三区久久 | 久久人人添人人爽添人人片牛牛 | 91精品国产乱码久久久久久 | 无码AV中文字幕久久专区| 久久国产精品免费一区二区三区| 久久亚洲精品中文字幕| 亚洲国产精品无码久久久久久曰| 亚洲午夜精品久久久久久人妖| 久久这里只有精品18| 伊人久久大香线蕉综合网站| 久久国产午夜精品一区二区三区| 久久国产精品久久国产精品| 久久久无码精品亚洲日韩按摩 | 久久亚洲天堂| 99久久精品免费看国产一区二区三区 | 国产三级久久久精品麻豆三级 | 青草影院天堂男人久久| 久久精品国产亚洲AV大全| 一本色道久久综合狠狠躁| 久久久久99这里有精品10| 伊人久久大香线蕉综合热线| 亚洲欧洲精品成人久久奇米网| 久久涩综合| 亚洲成av人片不卡无码久久| 午夜精品久久久久| 一本久久a久久精品亚洲| 久久精品国产亚洲AV无码偷窥| 伊人久久大香线焦AV综合影院 | 久久亚洲国产成人影院| 久久精品国产久精国产果冻传媒| 日韩精品久久久久久久电影蜜臀|