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

We do not always find visible happiness in proportion to visible virtue

夢幻白樺林

SHARE

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  14 Posts :: 58 Stories :: 62 Comments :: 0 Trackbacks

公告

常用鏈接

留言簿(5)

搜索

  •  

最新隨筆

最新評論

閱讀排行榜

委托(delegate)
  
  和成員函數(shù)指針不同,你不難發(fā)現(xiàn)委托的用處。最重要的,使用委托可以很容易地實現(xiàn)一個 Subject/Observer設計模式的改進版[GoF, p. 293]。Observer(觀察者)模式顯然在GUI中有很多的應用,但我發(fā)現(xiàn)它對應用程序核心的設計也有很大的作用。委托也可用來實現(xiàn)策略(Strategy)[GoF, p. 315]和狀態(tài)(State)[GoF, p. 305]模式。
  
  現(xiàn)在,我來說明一個事實,委托和成員函數(shù)指針相比并不僅僅是好用,而且比成員函數(shù)指針簡單得多!既然所有的.NET語言都實現(xiàn)了委托,你可能會猜想如此高層的概念在匯編代碼中并不好實現(xiàn)。但事實并不是這樣:委托的實現(xiàn)確實是一個底層的概念,而且就像普通的函數(shù)調(diào)用一樣簡單(并且很高效)。一個C++委托只需要包含一個this 指針和一個簡單的函數(shù)指針就夠了。當你建立一個委托時,你提供這個委托一個this指針,并向它指明需要調(diào)用哪一個函數(shù)。編譯器可以在建立委托時計算出調(diào)整this指針需要的偏移量。這樣在使用委托的時候,編譯器就什么事情都不用做了。這一點更好的是,編譯器可以在編譯時就可以完成全部這些工作,這樣的話,委托的處理對編譯器來說可以說是微不足道的工作了。在x86系統(tǒng)下將委托處理成的匯編代碼就應該是這么簡單:
  
  mov ecx, [this]
  
  call [pfunc]
  
  但是,在標準C++中卻不能生成如此高效的代碼。 Borland為了解決委托的問題在它的C++編譯器中加入了一個新的關(guān)鍵字(__closure),用來通過簡潔的語法生成優(yōu)化的代碼。GNU編譯器也對語言進行了擴展,但和Borland的編譯器不兼容。如果你使用了這兩種語言擴展中的一種,你就會限制自己只使用一個廠家的編譯器。而如果你仍然遵循標準C++的規(guī)則,你仍然可以實現(xiàn)委托,但實現(xiàn)的委托就不會是那么高效了。
  
  有趣的是,在C#和其他.NET語言中,執(zhí)行一個委托的時間要比一個函數(shù)調(diào)用慢8倍(參見http://msdn.microsoft.com/library/en- us/dndotnet/html/fastmanagedcode.asp)。我猜測這可能是垃圾收集和.NET安全檢查的需要。最近,微軟將“統(tǒng)一事件模型(unified event model)”加入到Visual C++中,隨著這個模型的加入,增加了__event、 __raise、__hook、__unhook、event_source和event_receiver等一些關(guān)鍵字。坦白地說,我對加入的這些特性很反感,因為這是完全不符合標準的,這些語法是丑陋的,因為它們使這種C++不像C++,并且會生成一堆執(zhí)行效率極低的代碼。
  
  解決這個問題的推動力:對高效委托(fast delegate)的迫切需求
  
  使用標準C++實現(xiàn)委托有一個過度臃腫的癥狀。大多數(shù)的實現(xiàn)方法使用的是同一種思路。這些方法的基本觀點是將成員函數(shù)指針看成委托??但這樣的指針只能被一個單獨的類使用。為了避免這種局限,你需要間接地使用另一種思路:你可以使用模版為每一個類建立一個“成員函數(shù)調(diào)用器(member function invoker)”。委托包含了this指針和一個指向調(diào)用器(invoker)的指針,并且需要在堆上為成員函數(shù)調(diào)用器分配空間。
  
  對于這種方案已經(jīng)有很多種實現(xiàn),包括在CodeProject上的實現(xiàn)方案。各種實現(xiàn)在復雜性上、語法(比如,有的和C#的語法很接近)上、一般性上有所不同。最具權(quán)威的一個實現(xiàn)是boost::function。最近,它已經(jīng)被采用作為下一個發(fā)布的C++標準版本中的一部分[Sutter1]。希望它能夠被廣泛地使用。
  
  就像傳統(tǒng)的委托實現(xiàn)方法一樣,我同樣發(fā)覺這種方法并不十分另人滿意。雖然它提供了大家所期望的功能,但是會混淆一個潛在的問題:人們?nèi)狈σ粋€語言的底層的構(gòu)造。 “成員函數(shù)調(diào)用器”的代碼對幾乎所有的類都是一樣的,在所有平臺上都出現(xiàn)這種情況是令人沮喪的。畢竟,堆被用上了。但在一些應用場合下,這種新的方法仍然無法被接受。
  
  我做的一個項目是離散事件模擬器,它的核心是一個事件調(diào)度程序,用來調(diào)用被模擬的對象的成員函數(shù)。大多數(shù)成員函數(shù)非常簡單:它們只改變對象的內(nèi)部狀態(tài),有時在事件隊列(event queue)中添加將來要發(fā)生的事件,在這種情況下最適合使用委托。但是,每一個委托只被調(diào)用(invoked)一次。一開始,我使用了boost:: function,但我發(fā)現(xiàn)程序運行時,給委托所分配的內(nèi)存空間占用了整個程序空間的三分之一還要多!“我要真正的委托!”我在內(nèi)心呼喊著,“真正的委托只需要僅僅兩行匯編指令啊!”
  
  我并不能總是能夠得到我想要的,但后來我很幸運。我在這兒展示的代碼(代碼下載鏈接見譯者注)幾乎在所有編譯環(huán)境中都產(chǎn)生了優(yōu)化的匯編代碼。最重要的是,調(diào)用一個含有單個目標的委托(single-target delegate)的速度幾乎同調(diào)用一個普通函數(shù)一樣快。實現(xiàn)這樣的代碼并沒有用到什么高深的東西,唯一的遺憾就是,為了實現(xiàn)目標,我的代碼和標準C++ 的規(guī)則有些偏離。我使用了一些有關(guān)成員函數(shù)指針的未公開知識才使它能夠這樣工作。如果你很細心,而且不在意在少數(shù)情況下的一些編譯器相關(guān)(compiler-specific)的代碼,那么高性能的委托機制在任何C++編譯器下都是可行的。
  
  訣竅:將任何類型的成員函數(shù)指針轉(zhuǎn)化為一個標準的形式
  
  我的代碼的核心是一個能夠?qū)⑷魏晤惖闹羔樅腿魏纬蓡T函數(shù)指針分別轉(zhuǎn)換為一個通用類的指針和一個通用成員函數(shù)的指針的類。由于C++沒有“通用成員函數(shù)(geneic member function)”的類型,所以我把所有類型的成員函數(shù)都轉(zhuǎn)化為一個在代碼中未定義的CGenericClass類的成員函數(shù)。
  
  大多數(shù)編譯器對所有的成員函數(shù)指針平等地對待,不管他們屬于哪個類。所以對這些編譯器來說,可以使用reinterpret_cast將一個特定的成員函數(shù)指針轉(zhuǎn)化為一個通用成員函數(shù)指針。事實上,假如編譯器不可以,那么這個編譯器是不符合標準的。對于一些接近標準(almost-compliant)的編譯器,比如Digital Mars,成員函數(shù)指針的reinterpret_cast轉(zhuǎn)換一般會涉及到一些額外的特殊代碼,當進行轉(zhuǎn)化的成員函數(shù)的類之間沒有任何關(guān)聯(lián)時,編譯器會出錯。對這些編譯器,我們使用一個名為horrible_cast的內(nèi)聯(lián)函數(shù)(在函數(shù)中使用了一個union來避免C++的類型檢查)。使用這種方法看來是不可避免的??boost::function也用到了這種方法。
  
  對于其他的一些編譯器(如Visual C++, Intel C++和Borland C++),我們必須將多重(multiple-)繼承和虛擬(virtual-)繼承類的成員函數(shù)指針轉(zhuǎn)化為單一(single-)繼承類的函數(shù)指針。為了實現(xiàn)這個目的,我巧妙地使用了模板并利用了一個奇妙的戲法。注意,這個戲法的使用是因為這些編譯器并不是完全符合標準的,但是使用這個戲法得到了回報:它使這些編譯器產(chǎn)生了優(yōu)化的代碼。
  
  既然我們知道編譯器是怎樣在內(nèi)部存儲成員函數(shù)指針的,并且我們知道在問題中應該怎樣為成員函數(shù)指針調(diào)整this指針,我們的代碼在設置委托時可以自己調(diào)整this指針。對單一繼承類的函數(shù)指針,則不需要進行調(diào)整;對多重繼承,則只需要一次加法就可完成調(diào)整;對虛擬繼承...就有些麻煩了。但是這樣做是管用的,并且在大多數(shù)情況下,所有的工作都在編譯時完成!
  
  這是最后一個訣竅。我們怎樣區(qū)分不同的繼承類型?并沒有官方的方法來讓我們區(qū)分一個類是多重繼承的還是其他類型的繼承。但是有一種巧妙的方法,你可以查看我在前面給出了一個列表(見中篇)——對MSVC,每種繼承方式產(chǎn)生的成員函數(shù)指針的大小是不同的。所以,我們可以基于成員函數(shù)指針的大小使用模版!比如對多重繼承類型來說,這只是個簡單的計算。而在確定unknown_inheritance(16字節(jié))類型的時候,也會采用類似的計算方法。
  
  對于微軟和英特爾的編譯器中采用不標準12字節(jié)的虛擬繼承類型的指針的情況,我引發(fā)了一個編譯時錯誤(compile-time error),因為需要一個特定的運行環(huán)境(workaround)。如果你在MSVC中使用虛擬繼承,要在聲明類之前使用 FASTDELEGATEDECLARE宏。而這個類必須使用unknown_inheritance(未知繼承類型)指針(這相當于一個假定的 __unknown_inheritance關(guān)鍵字)。例如:
  
FASTDELEGATEDECLARE(CDerivedClass)
  
  
class CDerivedClass : virtual public CBaseClass1, virtual public CBaseClass2 {
  
  
// : (etc)
  
  };

  
  這個宏和一些常數(shù)的聲明是在一個隱藏的命名空間中實現(xiàn)的,這樣在其他編譯器中使用時也是安全的。MSVC(7.0或更新版本)的另一種方法是在工程中使用/vmg編譯器選項。而Inter的編譯器對/vmg編譯器選項不起作用,所以你必須在虛擬繼承類中使用宏。我的這個代碼是因為編譯器的bug才可以正確運行,你可以查看代碼來了解更多細節(jié)。而在遵從標準的編譯器中不需要注意這么多,況且在任何情況下都不會妨礙FASTDELEGATEDECLARE宏的使用。
  
  一旦你將類的對象指針和成員函數(shù)指針轉(zhuǎn)化為標準形式,實現(xiàn)單一目標的委托(single-target delegate)就比較容易了(雖然做起來感覺冗長乏味)。你只要為每一種具有不同參數(shù)的函數(shù)制作相應的模板類就行了。實現(xiàn)其他類型的委托的代碼也大都與此相似,只是對參數(shù)稍做修改罷了。
  
  這種用非標準方式轉(zhuǎn)換實現(xiàn)的委托還有一個好處,就是委托對象之間可以用等式比較。目前實現(xiàn)的大多數(shù)委托無法做到這一點,這使這些委托不能勝任一些特定的任務,比如實現(xiàn)多播委托(multi-cast delegates) [Sutter3]。
  
  靜態(tài)函數(shù)作為委托目標(delegate target)
  
  理論上,一個簡單的非成員函數(shù)(non-member function),或者一個靜態(tài)成員函數(shù)(static member function)可以被作為委托目標(delegate target)。這可以通過將靜態(tài)函數(shù)轉(zhuǎn)換為一個成員函數(shù)來實現(xiàn)。我有兩種方法實現(xiàn)這一點,兩種方法都是通過使委托指向調(diào)用這個靜態(tài)函數(shù)的“調(diào)用器(invoker)”的成員函數(shù)的方法來實現(xiàn)的。
posted on 2007-06-08 00:18 colys 閱讀(492) 評論(0)  編輯 收藏 引用 所屬分類: C++

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美大片在线观看一区二区| 免费一区视频| 亚洲免费观看高清完整版在线观看熊 | 亚洲人成网站在线观看播放| 久久久久免费观看| 在线日韩日本国产亚洲| 嫩草国产精品入口| 欧美mv日韩mv国产网站app| 亚洲激情精品| 亚洲人成7777| 欧美性大战久久久久| 先锋影音国产精品| 久久国产天堂福利天堂| 一区二区三区在线观看国产| 欧美高清视频在线观看| 欧美激情视频一区二区三区不卡| 亚洲激情成人在线| 亚洲免费观看高清在线观看 | 国产精品乱子久久久久| 午夜精品久久久久久久男人的天堂 | 亚洲国产欧美一区二区三区同亚洲 | 欧美在线地址| 久久人人超碰| 在线性视频日韩欧美| 亚洲欧美综合精品久久成人| 激情综合亚洲| 亚洲精品少妇网址| 国产日韩欧美日韩| 亚洲激情女人| 国产日产亚洲精品| 亚洲国产精品激情在线观看 | 亚洲自拍电影| 一区二区三区在线观看视频| 亚洲精品美女在线观看| 国产精品一区二区三区乱码| 欧美成人精品影院| 国产精品成人一区二区三区吃奶 | 亚洲婷婷免费| 久久中文字幕导航| 亚洲欧美一区二区三区久久| 久久夜色撩人精品| 欧美亚洲一区三区| 欧美精品在线观看| 美日韩精品视频| 国产农村妇女毛片精品久久麻豆| 亚洲电影免费观看高清完整版在线| 国产精品久久久久久av福利软件 | 亚洲国产高清在线| 国模大胆一区二区三区| 一区二区高清视频| 亚洲精品小视频| 欧美在线亚洲| 午夜国产欧美理论在线播放| 欧美欧美全黄| 欧美搞黄网站| 有码中文亚洲精品| 欧美一区二区三区在线| 亚洲欧美日韩综合aⅴ视频| 欧美日韩成人在线播放| 亚洲国产一区二区三区青草影视| 国模私拍一区二区三区| 亚洲综合日本| 性欧美1819性猛交| 国产精品久久久久久久app| 99re成人精品视频| 一区二区三区|亚洲午夜| 欧美91精品| 欧美黄污视频| 亚洲黄色高清| 欧美国产综合视频| 最新成人av在线| 亚洲精品久久久久中文字幕欢迎你| 久久久久五月天| 免费成人黄色av| 在线精品视频一区二区三四| 久久嫩草精品久久久久| 狼狼综合久久久久综合网| 韩国在线一区| 久久久欧美精品| 亚洲国产精品va在线观看黑人| 亚洲大胆美女视频| 美女视频黄免费的久久| 亚洲电影下载| 亚洲视频精选在线| 欧美图区在线视频| 亚洲欧美日韩精品久久奇米色影视| 午夜一区不卡| 一区精品在线播放| 久久一区二区三区四区| 亚洲第一网站免费视频| 日韩视频二区| 国产精品国产三级欧美二区 | 亚洲成色777777女色窝| 亚洲美女毛片| 国产精品成人观看视频免费 | 欧美激情一区二区三区在线| 日韩视频一区二区在线观看 | 国产精品久久久久久模特| 亚洲男女自偷自拍| 美女黄色成人网| 一本久久综合| 国产在线高清精品| 欧美国产亚洲另类动漫| 国产精品99久久久久久www| 久久最新视频| 一区二区三区四区五区视频| 国产综合在线视频| 欧美日韩另类综合| 久久久久久久久久久久久9999| 亚洲国产成人av在线| 欧美一级一区| 99国内精品久久| 狠狠综合久久av一区二区老牛| 欧美激情一区二区三区| 欧美在线免费观看视频| 日韩视频在线免费| 久久综合激情| 亚洲欧美综合v| 日韩小视频在线观看专区| 国产日韩综合一区二区性色av| 欧美成ee人免费视频| 亚洲欧美视频| 亚洲精品乱码久久久久久| 久久女同精品一区二区| 亚洲欧美一区二区三区在线 | 国产精品日日摸夜夜摸av| 欧美mv日韩mv亚洲| 久久久久国产一区二区| 亚洲综合丁香| 一区二区免费看| 亚洲日本中文| 亚洲国产精品一区二区www在线| 欧美在线观看视频一区二区三区| 日韩一级黄色大片| 亚洲激情偷拍| 亚洲国产免费看| 亚洲第一精品影视| 国产区亚洲区欧美区| 国产精品久久夜| 欧美日韩在线精品一区二区三区| 免费视频一区二区三区在线观看| 久久久久国产精品人| 久久久国产精品一区| 性欧美大战久久久久久久免费观看| 一本色道久久综合| 一区二区三区四区蜜桃| 亚洲精品乱码| 洋洋av久久久久久久一区| 亚洲肉体裸体xxxx137| 最新亚洲一区| 日韩视频一区二区| 日韩亚洲成人av在线| 亚洲免费精彩视频| av成人老司机| 亚洲男女毛片无遮挡| 欧美一区二区成人| 久久精品国产96久久久香蕉| 欧美一区二区三区在线观看视频 | 亚洲精品视频一区二区三区| 亚洲精品国产拍免费91在线| 亚洲黄网站黄| 亚洲最黄网站| 性欧美办公室18xxxxhd| 久久精品夜色噜噜亚洲aⅴ| 久久日韩粉嫩一区二区三区| 欧美成人午夜视频| 欧美日韩三区| 国产亚洲精品aa| 18成人免费观看视频| 日韩一区二区精品葵司在线| 亚洲免费一在线| 久久久久国色av免费看影院 | 在线午夜精品| 午夜精品福利在线| 老牛嫩草一区二区三区日本| 欧美成人69| 这里只有视频精品| 欧美在线网站| 欧美精品一区二区三区很污很色的 | 欧美一级久久| 欧美成人第一页| 国产精品看片你懂得| 国内精品久久久久久久果冻传媒| 亚洲第一黄色| 亚洲欧美另类在线观看| 欧美bbbxxxxx| 亚洲欧美激情四射在线日| 久久综合导航| 国产精品视频久久| 亚洲国产日日夜夜| 久久成年人视频| 日韩天堂在线视频| 久久久精品tv| 国产精品午夜国产小视频| 亚洲人精品午夜| 久久亚洲精品伦理| 一区二区三区鲁丝不卡| 欧美不卡高清| 韩日在线一区| 午夜精品福利视频|