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

C++分析研究  
C++
日歷
<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
統(tǒng)計(jì)
  • 隨筆 - 92
  • 文章 - 4
  • 評(píng)論 - 4
  • 引用 - 0

導(dǎo)航

常用鏈接

留言簿

隨筆檔案

文章檔案

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

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

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

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

  再來看另外一個(gè)不用析構(gòu)函數(shù)的例子,想象一下設(shè)計(jì)一個(gè)圖書館類。我們將MaterialLocation作為抽象類LibraryMaterial的一個(gè)成員。將它的print成員函數(shù)聲明為一個(gè)純虛函數(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; }

  接著,我們引入一個(gè)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.

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

  LibraryMaterial *p =

  new AudioBook( "Mason &Dixon",

  "Thomas Pynchon", "Johnny Depp" );

  // ...

  p->print();

  這個(gè)print實(shí)例是內(nèi)聯(lián)的嗎?不,當(dāng)然不是。這樣不得不通過虛擬機(jī)制在運(yùn)行期決議。這讓print實(shí)例放棄了對(duì)它的內(nèi)聯(lián)聲明了嗎?也不是。這個(gè)調(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.因?yàn)檎{(diào)用print是通過函數(shù)指針_vptr[2]進(jìn)行的,所以,編譯器不能靜態(tài)的決定這個(gè)調(diào)用地址,并且,這個(gè)函數(shù)也不能內(nèi)聯(lián)。

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

  在一個(gè)可應(yīng)用的類[b]中有多少vitrual table會(huì)被生成呢?呵呵,這是一個(gè)好問題。C++標(biāo)準(zhǔn)中對(duì)虛函數(shù)行為進(jìn)行了規(guī)定,但是沒有對(duì)函數(shù)實(shí)現(xiàn)進(jìn)行規(guī)定。由于virtual table沒有在C++標(biāo)準(zhǔn)中進(jìn)行規(guī)定,很明顯,究竟這個(gè)virtual table怎樣生成,和究竟要生成多少個(gè)vitrual table也沒有規(guī)定。多少個(gè)?當(dāng)然,我們只要一個(gè)。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ī)則要求編譯器只展開一個(gè)內(nèi)聯(lián)虛函數(shù)。如果一點(diǎn)被廣泛采用的話,虛函數(shù)的內(nèi)聯(lián)導(dǎo)致的代碼膨脹問題就會(huì)消失。 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ù)的時(shí)候至少要經(jīng)過兩次間接過程(S. B.Lippman: 《Inside the C++ Object Model》)

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

  總結(jié):

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

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

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

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

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

  保證代碼不過度膨脹

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

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


 
Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
PK10開獎(jiǎng) PK10開獎(jiǎ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>
            欧美成人一区二区在线| 欧美日韩中文字幕在线| 亚洲精品久久久蜜桃| 91久久综合| 蜜臀久久99精品久久久画质超高清| 亚洲国产三级| 亚洲乱码一区二区| 国产精品视频区| 久久久久一区| 蜜桃久久精品乱码一区二区| 在线亚洲电影| 亚洲欧美在线播放| 亚洲国产合集| 亚洲国产成人精品女人久久久 | 亚洲一区二区三区精品在线观看| 国产欧美日韩麻豆91| 美女任你摸久久| 欧美日韩另类综合| 久久成人免费网| 麻豆成人在线播放| 亚洲制服丝袜在线| 久久久91精品国产一区二区三区| 亚洲日韩欧美视频一区| 亚洲性感激情| 在线观看日韩一区| 99精品黄色片免费大全| 国产一区日韩欧美| 亚洲欧洲精品一区二区三区| 国产精品视频男人的天堂| 欧美国产一区二区| 国产精品久久久久久五月尺| 麻豆国产精品一区二区三区 | 国产精品激情电影| 久久亚洲一区二区三区四区| 欧美极品欧美精品欧美视频| 欧美在线精品一区| 欧美国产日韩一区二区三区| 欧美在线播放一区二区| 蜜桃精品久久久久久久免费影院| 亚洲欧美亚洲| 欧美成人免费小视频| 欧美影院精品一区| 欧美激情精品久久久久久蜜臀| 欧美一区二区三区啪啪| 欧美sm视频| 久久精品国产v日韩v亚洲| 欧美精品1区2区3区| 久久免费视频这里只有精品| 欧美三级视频在线| 欧美国产1区2区| 国产拍揄自揄精品视频麻豆| 亚洲欧洲日产国码二区| 黑人一区二区| 亚洲一级影院| 日韩手机在线导航| 久久另类ts人妖一区二区| 亚洲免费在线播放| 欧美成人福利视频| 久久婷婷av| 国产精品日韩高清| 亚洲伦理一区| 亚洲精品综合精品自拍| 久久精品盗摄| 欧美一区二区精品久久911| 欧美精品国产精品日韩精品| 另类激情亚洲| 国产午夜精品久久| 亚洲深夜福利视频| 最新日韩在线视频| 久久久久成人精品免费播放动漫| 午夜精品久久| 欧美日韩亚洲一区二区三区在线观看 | 欧美xart系列高清| 国产午夜精品久久| 亚洲免费在线电影| 亚洲伊人伊色伊影伊综合网| 欧美激情五月| 欧美电影免费观看| 欲色影视综合吧| 久久国产精品一区二区三区四区| 香蕉精品999视频一区二区| 欧美日韩亚洲一区| 亚洲乱码精品一二三四区日韩在线| 亚洲人成7777| 美女网站在线免费欧美精品| 久久夜色精品国产噜噜av| 国产日本亚洲高清| 亚洲欧美日韩国产综合在线 | 亚洲电影av| 亚洲国产va精品久久久不卡综合| 欧美在线视频全部完| 久久av一区| 国产欧美婷婷中文| 午夜精品福利一区二区三区av| 亚洲欧美激情视频| 国产精品黄色| 亚洲午夜免费视频| 午夜精品视频在线观看| 国产精品久久久久久久久搜平片 | 国产精品乱人伦中文| 一区二区三区黄色| 亚洲女人av| 国产精品日日摸夜夜摸av| 亚洲一区二区三区色| 午夜国产精品视频| 国产精品午夜春色av| 亚洲综合精品自拍| 欧美中文字幕在线视频| 国产色爱av资源综合区| 午夜精品一区二区三区在线| 久久成人免费视频| 精品69视频一区二区三区| 久久久五月天| 欧美激情麻豆| 99精品久久免费看蜜臀剧情介绍| 欧美久久久久免费| 夜夜嗨一区二区三区| 亚洲欧美中文日韩v在线观看| 国产美女精品视频免费观看| 欧美一级片一区| 美女主播一区| 亚洲精品日产精品乱码不卡| 欧美人牲a欧美精品| 中文国产成人精品| 欧美在线1区| 加勒比av一区二区| 欧美二区不卡| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美日韩中文另类| 亚洲一区二区视频在线观看| 久久激情五月激情| 亚洲成人在线| 欧美日韩成人网| 亚洲一级在线观看| 葵司免费一区二区三区四区五区| 亚洲高清色综合| 欧美日韩国产精品一卡| 亚洲一区视频在线观看视频| 久久婷婷国产综合精品青草| 亚洲欧洲在线一区| 国产精品成人va在线观看| 香蕉成人久久| 亚洲成色999久久网站| 亚洲视频精品| 国产亚洲欧美一级| 欧美成人国产va精品日本一级| 日韩视频在线一区| 久久久www| 亚洲免费黄色| 国产美女精品视频| 欧美成人国产一区二区| 中国成人在线视频| 老鸭窝91久久精品色噜噜导演| 亚洲精品久久久久久一区二区| 国产精品露脸自拍| 久久综合九九| 亚洲视频每日更新| 免费影视亚洲| 亚洲男人av电影| 在线欧美小视频| 国产精品v欧美精品v日韩精品| 久久精品国产清高在天天线| 亚洲美女啪啪| 老色批av在线精品| 亚洲特色特黄| 在线国产日韩| 国产精品久久久久999| 久久视频一区| 亚洲一区欧美| 亚洲激情电影在线| 久久精品九九| 一区二区日韩伦理片| 韩国一区电影| 欧美性开放视频| 麻豆av福利av久久av| 亚洲欧美日韩在线一区| 亚洲国产精品ⅴa在线观看| 欧美在线999| 一区二区三区成人精品| 伊人狠狠色j香婷婷综合| 国产精品国产三级国产专播品爱网| 欧美一区二区视频观看视频| 亚洲小说春色综合另类电影| 韩国精品在线观看| 国产精品r级在线| 久久五月婷婷丁香社区| 亚洲夜晚福利在线观看| 亚洲全部视频| 蜜臀av国产精品久久久久| 午夜欧美不卡精品aaaaa| 日韩午夜激情电影| 在线成人小视频| 国产色爱av资源综合区| 欧美午夜无遮挡| 欧美国产精品人人做人人爱| 久久激情综合网| 亚洲欧美成人| 一区二区三区av| 最新国产成人在线观看| 欧美顶级大胆免费视频|