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

C++分析研究  
C++
日歷
<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456
統(tǒng)計
  • 隨筆 - 92
  • 文章 - 4
  • 評論 - 4
  • 引用 - 0

導(dǎo)航

常用鏈接

留言簿

隨筆檔案

文章檔案

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

 
  我們曾經(jīng)在討論C++的時候,經(jīng)常會問到:“虛函數(shù)能被聲明為內(nèi)聯(lián)嗎?”現(xiàn)在,我們幾乎聽不到這個問題了。現(xiàn)在聽到的是:“你不應(yīng)該使print成為內(nèi)聯(lián)的。聲明一個虛函數(shù)為內(nèi)聯(lián)是錯誤的!”

  這種說法的兩個主要的原因是(1)虛函數(shù)是在運行期決議而內(nèi)聯(lián)是一個編譯期動作,所以,我們將虛函數(shù)聲明為內(nèi)聯(lián)并得不到什么效果;(2)聲明一個虛函數(shù)為內(nèi)聯(lián)導(dǎo)致了函數(shù)的多分拷貝,而且我們?yōu)橐粋€不應(yīng)該在任何時候內(nèi)聯(lián)的函數(shù)白白花費了存儲空間。這樣做很沒腦子。 www.601456.com

  不過,事實并不是這樣。我們先來看看第一個:許多情況下,虛擬函數(shù)都被靜態(tài)地決議了——比如在派生類虛擬函數(shù)中調(diào)用基類的虛擬函數(shù)的時候。為什么這樣做呢?封裝。一個比較明顯的例子就是派生類析構(gòu)函數(shù)調(diào)用鏈。所有的虛析構(gòu)函數(shù),除了最初觸發(fā)這個析構(gòu)鏈的虛析構(gòu)函數(shù),都被靜態(tài)的決議了。如果不將基類的虛析構(gòu)函數(shù)內(nèi)聯(lián),我們無法從中獲利[a]。這和不內(nèi)聯(lián)一個虛擬析構(gòu)函數(shù)有什么不同嗎?如果繼承體系層次比較深并且有許多這樣的類的實例要被銷毀的話,答案是肯定的。

  再來看另外一個不用析構(gòu)函數(shù)的例子,想象一下設(shè)計一個圖書館類。我們將MaterialLocation作為抽象類LibraryMaterial的一個成員。將它的print成員函數(shù)聲明為一個純虛函數(shù),并且提供函數(shù)定義:它輸出MaterialLocation。

  class LibraryMaterial {

  private:

  MaterialLocation _loc; // shared data

  // ...

  public:

  // declares pure virtual function

  inline virtual void print( ostream& = cout ) = 0;

  };

  // we actually want to encapsulate the handling of the

  // location of the material within a base class

  // LibraryMaterial print() method - we just don’t want it

  // invoked through the virtual interface. That is, it is

  // only to be invoked within a derived class print() method

  inline void

  LibraryMaterial::

  print( ostream &os ) { os <<_loc; }

  接著,我們引入一個Book類,它的print函數(shù)輸出Title, Author等等。在這之前,它調(diào)用基類的print函數(shù)(LibraryMaterial::print())來顯示書本位置(MaterialLocation)。如下:

  inline void

  Book:: www.liuhebao.com

  print( ostream &os )

  {

  // ok, this is resolved statically,

  // and therefore is inline expanded ...

  LibraryMaterial::print();

  os <<"title:" <<_title

  << "author" <<_author < www.szfuao.com

  AudioBook類,派生于Book類,并加入附加信息,比如旁述,音頻格式等等。這些東西都用它的print函數(shù)輸出。再這之前,我們需要調(diào)用Book::print()來顯示前面的信息。

  inline void

  AudioBook::

  print( ostream &os )

  {

  // ok, this is resolved statically,

  // and therefore is inline expanded ...

  Book::print(); www.yzjxsp.com

  os <<"narrator:" <<_narrator <

  }

  這和虛析構(gòu)函數(shù)調(diào)用鏈的例子一樣,都只是最初調(diào)用的虛函數(shù)沒有被靜態(tài)決議,其它的都被原地展開。This unnamed hierarchical design pattern is significantly less effective if we never declare a virtual function to be inline.

  那么對于第二個原因中代碼膨脹的問題呢?我們來分析一下,如果我們寫下:

  LibraryMaterial *p =

  new AudioBook( "Mason &Dixon",

  "Thomas Pynchon", "Johnny Depp" );

  // ...

  p->print();

  這個print實例是內(nèi)聯(lián)的嗎?不,當(dāng)然不是。這樣不得不通過虛擬機制在運行期決議。這讓print實例放棄了對它的內(nèi)聯(lián)聲明了嗎?也不是。這個調(diào)用轉(zhuǎn)換為下面的形式(偽代碼):

  // Pseudo C++Code www.yzsws.com

  // Possible transformation of p->print()

  ( *p->_vptr[ 2 ] )( p );

  where 2 represents the location of print within the associated virtual function table.因為調(diào)用print是通過函數(shù)指針_vptr[2]進行的,所以,編譯器不能靜態(tài)的決定這個調(diào)用地址,并且,這個函數(shù)也不能內(nèi)聯(lián)。

  當(dāng)然,虛函數(shù)print的內(nèi)聯(lián)實體(definition)也必須在某個地方表現(xiàn)出來。 即是說,至少有一個函數(shù)實體是在virtual table調(diào)用的地址原地展開的。編譯器是如何決定在何時展開這個函數(shù)實體呢?其中一個編譯(implementaion)策略是當(dāng)virtual table生成的同時,生成這個函數(shù)實體。這就是說對于每一個派生類的virtual table都會生成一個函數(shù)實體。

  在一個可應(yīng)用的類[b]中有多少vitrual table會被生成呢?呵呵,這是一個好問題。C++標(biāo)準(zhǔn)中對虛函數(shù)行為進行了規(guī)定,但是沒有對函數(shù)實現(xiàn)進行規(guī)定。由于virtual table沒有在C++標(biāo)準(zhǔn)中進行規(guī)定,很明顯,究竟這個virtual table怎樣生成,和究竟要生成多少個vitrual table也沒有規(guī)定。多少個?當(dāng)然,我們只要一個。Stroustrup的cfront編譯器,很巧妙的處理了這些情況.( Stan and Andy Koenig described the algorithm in the March 1990 C++ Report article, "Optimizing Virtual Tables in C++ Release 2.0.")

  Moreover, the C++ Standard now requires that inline functions behave as though only one definition for an inline function exists in the program even though the function may be defined in different files。新的規(guī)則要求編譯器只展開一個內(nèi)聯(lián)虛函數(shù)。如果一點被廣泛采用的話,虛函數(shù)的內(nèi)聯(lián)導(dǎo)致的代碼膨脹問題就會消失。 www.yzyedu.com

  [譯注:C++ Standard: 9.3.8, Member function of local class shall be defined inline in their class defination, if they are defined at all]

  ============================

  譯注:

  [a]函數(shù)調(diào)用開銷,調(diào)用基類虛函數(shù)的時候至少要經(jīng)過兩次間接過程(S. B.Lippman: 《Inside the C++ Object Model》)

  [b]一個產(chǎn)品類(?)

  總結(jié):

  就是虛函數(shù)inline在調(diào)用鏈等地方很有用~

  即使沒有加入inline聲明,作為一個好編譯器,都會優(yōu)化(虛析構(gòu)函數(shù))

  在很長的函數(shù)調(diào)用鏈中,最好將鏈中基類的函數(shù)inline,這樣節(jié)約開銷

  至于在什么地方inline,由編譯器決定,因為C++標(biāo)準(zhǔn)沒有規(guī)定

  新C++標(biāo)準(zhǔn)(可能沒有通過)中,規(guī)定了,inline化只對產(chǎn)品類有效,且只動作一次

  保證代碼不過度膨脹

  inline動作是在產(chǎn)品類實例化同時,和vtable生成一起
posted on 2011-02-20 23:41 HAOSOLA 閱讀(199) 評論(0)  編輯 收藏 引用

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


 
Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
PK10開獎 PK10開獎
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲视频香蕉人妖| 久久精品主播| 国产欧美一区二区精品忘忧草| 欧美极品在线观看| 欧美激情综合在线| 欧美日韩久久不卡| 欧美日韩中字| 国产精品久久久久一区| 国产精品一区2区| 国产欧美一区二区三区另类精品 | 亚洲欧洲精品一区| 亚洲国产高清一区二区三区| 亚洲精品久久久久久下一站| 国产欧美日韩一区二区三区在线观看 | 午夜精品福利电影| 久久精品动漫| 亚洲国产成人精品女人久久久| 亚洲电影在线看| 一区二区三区久久| 久久精品72免费观看| 久久在线免费观看| 欧美日本韩国一区二区三区| 国产欧美一区二区三区在线老狼 | 亚洲欧美国产另类| 欧美国产免费| 99精品国产在热久久婷婷| 欧美一区二区黄| 欧美激情综合网| 韩国一区二区在线观看| 999亚洲国产精| 午夜在线精品偷拍| 久久激情婷婷| 国产精品草莓在线免费观看| 伊大人香蕉综合8在线视| 亚洲综合大片69999| 欧美激情精品久久久久| 黄色成人在线网址| 久久成年人视频| 欧美视频在线一区| 亚洲国产成人精品女人久久久| 久久天天狠狠| 国产欧美一区二区三区在线老狼| 一区二区三区四区国产| 美女黄色成人网| 久久久精品国产一区二区三区 | 欧美成人免费网| 午夜欧美不卡精品aaaaa| 欧美精品成人在线| 欧美一区二区观看视频| 亚洲国产综合视频在线观看| 欧美一区2区视频在线观看| 欧美午夜不卡| 国产精品99久久久久久久久| 欧美激情在线免费观看| 老司机精品视频网站| 一区二区在线视频| 久久日韩粉嫩一区二区三区| 亚洲欧美日韩一区在线| 国产精品美女久久久久久久| 亚洲亚洲精品三区日韩精品在线视频 | 国产日韩欧美视频| 欧美在线免费观看| 亚洲视屏在线播放| 久久人人爽人人爽爽久久| 国内自拍一区| 久久影视精品| 久久久久国内| 亚洲第一综合天堂另类专| 久久中文久久字幕| 欧美手机在线视频| 亚洲一区二区三区免费观看| 99精品视频网| 国产精品久久久久一区二区三区 | 欧美**人妖| 久久婷婷国产麻豆91天堂| 黄色成人在线| 亚洲国产美女| 欧美区日韩区| 亚洲欧美成人| 久久精品国产77777蜜臀| 午夜免费日韩视频| 狠狠色伊人亚洲综合成人| 老鸭窝亚洲一区二区三区| 免费久久99精品国产自在现线| 亚洲免费电影在线观看| 99国产精品自拍| 免费成人av在线| 亚洲免费大片| 国产婷婷色综合av蜜臀av | 在线一区欧美| 亚洲欧美日韩精品久久久| 免费成人黄色av| 欧美激情aaaa| 欧美视频一区二区三区四区| 久久成人综合网| 免费亚洲视频| 欧美一区二区三区日韩| 久久久国产午夜精品| 一本不卡影院| 久久裸体视频| 欧美视频日韩视频| 免费的成人av| 国产精品免费电影| 欧美成人免费在线观看| 国产精品久久久久一区二区三区 | 国产视频精品va久久久久久| 欧美国产综合| 国产精品视频免费观看| 欧美成人精品三级在线观看| 欧美视频精品在线| 欧美激情欧美激情在线五月| 国产伦精品一区二区三区照片91 | 老司机免费视频一区二区三区| 欧美精品在线免费| 久久精品视频一| 欧美视频三区在线播放| 亚洲精品久久久久久久久久久久| 午夜精品福利一区二区蜜股av| 一本色道久久综合亚洲精品小说 | 欧美成人精品在线播放| 午夜日韩在线观看| 欧美伦理影院| 亚洲国产高清在线| 亚洲电影毛片| 久久超碰97中文字幕| 欧美亚洲在线| 国产精品久久看| 一区二区91| 中文成人激情娱乐网| 欧美精品啪啪| 亚洲国产欧洲综合997久久| 在线国产亚洲欧美| 久久综合一区| 欧美福利网址| 亚洲第一伊人| 亚洲二区三区四区| 亚洲丰满在线| 美国十次成人| 久久亚洲国产成人| 狠狠综合久久| 久久久五月天| 欧美激情va永久在线播放| 一区二区三区鲁丝不卡| 国产精品久久毛片a| 男女视频一区二区| 亚洲国产婷婷| 亚洲人体一区| 欧美精品91| 亚洲精品少妇30p| 夜夜夜久久久| 欧美日韩综合另类| 亚洲欧美日韩一区二区| 久久久青草青青国产亚洲免观| 在线精品观看| 欧美电影免费网站| 一区二区三区日韩欧美| 午夜久久电影网| 伊人一区二区三区久久精品| 美女黄毛**国产精品啪啪| 正在播放欧美一区| 国产精品普通话对白| 亚洲欧美日韩系列| 欧美成人综合| 亚洲综合首页| 国产在线不卡视频| 欧美成人免费全部| 亚洲视频图片小说| 亚洲在线电影| 久久av在线看| 亚洲精品久久久久久下一站| 国产精品久久久久毛片大屁完整版| 欧美一区二区国产| 国产精品欧美久久久久无广告| 亚洲肉体裸体xxxx137| 欧美午夜电影一区| 久久国产精品第一页| 亚洲人成毛片在线播放女女| 欧美影院一区| 亚洲美女一区| 国产亚洲激情在线| 欧美激情中文字幕乱码免费| 亚洲欧美怡红院| 91久久综合亚洲鲁鲁五月天| 久久黄色级2电影| 一二三区精品| 久久青草久久| 亚洲私人影吧| 亚洲黄页一区| 蜜臀91精品一区二区三区| 亚洲调教视频在线观看| 亚洲第一精品电影| 国产精品尤物福利片在线观看| 免费成人黄色片| 亚洲精品欧美激情| 欧美成人精品1314www| 欧美在线日韩| 亚洲一区二区三区影院| 99国产精品久久| 亚洲福利一区| 蜜臀久久久99精品久久久久久|