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

洛譯小筑

別來無恙,我的老友…
隨筆 - 45, 文章 - 0, 評論 - 172, 引用 - 0
數(shù)據(jù)加載中……

[ECPP讀書筆記 條目37] 避免對函數(shù)中繼承得來的默認(rèn)參數(shù)值進(jìn)行重定義

讓我們開門見山的討論本話題:可以繼承的函數(shù)可以分為兩種:虛擬的和非虛擬的。然而,由于重定義一個派生的非虛函數(shù)始終是一個錯誤(參見條目36),因此我們可以放心地將此處的討論范圍縮小至以下情況:繼承一個含有默認(rèn)參數(shù)值的函數(shù)。

此情況下,證明本條目的結(jié)論非常簡單:虛函數(shù)是動態(tài)綁定的,而默認(rèn)參數(shù)值是靜態(tài)綁定的。

你說啥?靜態(tài)綁定與動態(tài)綁定之間的區(qū)別已經(jīng)讓你頭暈?zāi)垦A耍浚ū娝苤o態(tài)綁定又稱早期綁定,動態(tài)綁定又稱晚期綁定。)我們只好復(fù)習(xí)一下了。

一個對象的靜態(tài)類型就是你在對其進(jìn)行聲明時賦予它的類型。請考慮下面的類層次結(jié)構(gòu): 

// 幾何形狀類

class Shape {

public:

  enum ShapeColor { Red, Green, Blue };

 

  // 所有形狀必須提供一個自我繪制函數(shù)
  virtual void draw(ShapeColor color = Red) const = 0;

  ...

};

 

class Rectangle: public Shape {

public:

  // 請注意:默認(rèn)參數(shù)值變了——糟糕!

  virtual void draw(ShapeColor color = Green) const;

  ...

};

 

class Circle: public Shape {

public:

  virtual void draw(ShapeColor color) const;

  ...

};

用UML來表示:


現(xiàn)在請考慮下面的指針:

Shape *ps;                        // 靜態(tài)類型 = Shape*

Shape *pc = new Circle;           // 靜態(tài)類型 = Shape*

Shape *pr = new Rectangle;        // 靜態(tài)類型 = Shape*

示例中,由于pspc以及pr都聲明為指向Shape的指針,因此他們的靜態(tài)類型均為Shape*。請注意,這樣做使得無論他們實(shí)際指向的對象是什么類型,他們的靜態(tài)類型都必為Shape*

對象的動態(tài)類型是通過他當(dāng)前引用的對象的類型決定的。也就是說,動態(tài)類型表明了他應(yīng)具有怎樣的行為。在上文的示例中,pc的動態(tài)類型是Circle*pr的動態(tài)類型是Rectangle*。而對于ps來說,他在當(dāng)前根本不具備動態(tài)類型,因?yàn)樗壳埃┻€沒有引用任何對象呢。

動態(tài)類型,顧名思義,在程序運(yùn)行時可能會有所改變,通常是通過賦值操作發(fā)生: 

ps = pc;                           // ps動態(tài)類型變?yōu)?/span>Circle*

ps = pr;                           // ps動態(tài)類型變?yōu)?/span>Rectangle*

虛函數(shù)是動態(tài)綁定的,這就意味著,對于一個特定的函數(shù)調(diào)用,其調(diào)用對象的動態(tài)類型將決定調(diào)用這一函數(shù)的哪個版本: 

pc->draw(Shape::Red);              // 調(diào)用 Circle::draw(Shape::Red)

pr->draw(Shape::Red);              // 調(diào)用 Rectangle::draw(Shape::Red)

我知道這些都是老生常談了,你當(dāng)然已經(jīng)對虛函數(shù)有了透徹的理解。只有在虛函數(shù)包含默認(rèn)參數(shù)值時,情況才有所不同。這是因?yàn)椋ㄈ缟衔乃觯摵瘮?shù)是動態(tài)綁定的,但是默認(rèn)參數(shù)是靜態(tài)綁定的。這也就意味著對于一個虛函數(shù),你可能會調(diào)用它在派生類中的定義,而默認(rèn)參數(shù)值則采用基類中的值: 

pr->draw();                   // 調(diào)用 Rectangle::draw(Shape::Red)!

這種情況下,由于pr的動態(tài)類型是Rectangle*,于是此處便調(diào)用了虛函數(shù)drawRectangle版本,正如你所愿。在Rectangle::draw中,默認(rèn)參數(shù)值是Green。然而,因?yàn)?span style="font-family:"Courier New";">pr的靜態(tài)類型是Shape*,這里的draw調(diào)用將采用Shape類中的默認(rèn)參數(shù)值,而不是Rectangle!最終,在Shape類和Rectangle類之間,對于draw的調(diào)用必將出現(xiàn)混亂的無法預(yù)知的現(xiàn)象。

雖然pspcpr是指針,但是并不影響上文的結(jié)論。如果它們是引用的話,問題同樣存在。這里只有一個重點(diǎn):draw是虛函數(shù),他的一個默認(rèn)參數(shù)值在派生類中被重定義了。

是什么讓C++在處理這一問題時如此不合常理? 答案是:運(yùn)行時效率。如果默認(rèn)參數(shù)值是動態(tài)綁定的話,那么編譯器必須提供一整套方案,為運(yùn)行時的虛函數(shù)參數(shù)確定恰當(dāng)?shù)哪J(rèn)值。而這樣做,比起C++當(dāng)前使用的編譯時決定機(jī)制而言,將會更復(fù)雜、更慢。魚和熊掌不可兼得,C++將設(shè)計的中心傾向了速度和簡潔,你在享受效率的快感的同時,如果你忽略本條目的建議,你就會陷入困惑。

一切看上去似乎盡善盡美了,但是一旦你不假思索的遵守本條建議,為基類和派生類分別提供默認(rèn)參數(shù)值的話,看看將會發(fā)生什么: 

class Shape {

public:

  enum ShapeColor { Red, Green, Blue };

 

  virtual void draw(ShapeColor color = Red) const = 0;

  ...

};

class Rectangle: public Shape {

public:

  virtual void draw(ShapeColor color = Red) const;

  ...

};

 吁……惱人的重復(fù)代碼。還有更糟的:這些重復(fù)代碼彼此還有依賴:如果Shape中的默認(rèn)參數(shù)值改變了的話,那么所有的派生類中相應(yīng)的值都必須改變。否則這些函數(shù)仍將改變繼承來的默認(rèn)參數(shù)值。那么怎么辦呢?

遇到麻煩了?虛函數(shù)無法按照你預(yù)想的方式運(yùn)行?這時候明智的做法是:考慮一個替代的設(shè)計方案,條目35中介紹了幾種虛函數(shù)的替代方案。其中一種是非虛擬接口慣用法方案(NVI慣用法):在基類中用一個公有的非虛函數(shù)調(diào)用一個私有的虛函數(shù),并在派生類中重定義這一虛函數(shù)。在這里,我們將默認(rèn)參數(shù)置于非虛函數(shù)中,讓虛函數(shù)做具體的工作。

class Shape {

public:

  enum ShapeColor { Red, Green, Blue };

 

  void draw(ShapeColor color = Red) const

  {                                // 現(xiàn)在draw是非虛函數(shù)

doDraw(color);                 // 調(diào)用一個虛函數(shù)

  }

 ... 

private:

  virtual void doDraw(ShapeColor color) const = 0;

                                   // 這個函數(shù)做真正的工作

};

 

class Rectangle: public Shape {

public:

  ...

private:
  virtual void doDraw(ShapeColor color) const; 

                                   //此處不需要默認(rèn)參數(shù)值
  ...

};

 由于在派生類中不能對非虛函數(shù)進(jìn)行重載(參見條目36),因此,顯然地,這一設(shè)計方案使得draw函數(shù)中color參數(shù)的默認(rèn)值永遠(yuǎn)為Red


時刻牢記

避免在對函數(shù)中繼承得來的默認(rèn)參數(shù)值進(jìn)行重定義,這是因?yàn)槟J(rèn)參數(shù)值是靜態(tài)綁定的,而虛函數(shù)(派生類中唯一的一系列可以重定義的函數(shù))是動態(tài)綁定的。

posted on 2012-05-20 11:21 ★ROY★ 閱讀(2131) 評論(0)  編輯 收藏 引用 所屬分類: Effective 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>
            欧美在线免费视频| 老牛嫩草一区二区三区日本| 欧美视频日韩视频| 欧美午夜视频一区二区| 欧美三级电影一区| 国产精品亚洲激情| 黄网站色欧美视频| 91久久久久| 亚洲无线一线二线三线区别av| 午夜精彩国产免费不卡不顿大片| 久久精品免费电影| 欧美激情国产高清| 艳女tv在线观看国产一区| 午夜视频精品| 欧美国产精品v| 国产日产亚洲精品| 亚洲欧洲在线免费| 性感少妇一区| 亚洲成人自拍视频| 亚洲美女免费视频| 翔田千里一区二区| 欧美日本国产一区| 精品99视频| 亚洲伊人网站| 欧美成人a视频| 亚洲一区二区三区四区中文| 玖玖在线精品| 国产精品久久久999| 在线播放日韩| 亚洲欧美日韩另类精品一区二区三区| 久久久久久久久蜜桃| 亚洲精品在线观看免费| 亚洲黄色影院| 欧美日本韩国一区二区三区| 国产一级一区二区| 亚洲午夜一区| 亚洲国内自拍| 乱中年女人伦av一区二区| 国产欧美综合一区二区三区| 亚洲精品裸体| 欧美超级免费视 在线| 亚洲欧美日韩区| 欧美午夜不卡| 在线视频你懂得一区二区三区| 女人香蕉久久**毛片精品| 性久久久久久久久| 国产精品高潮粉嫩av| 99riav国产精品| 亚洲国产精品久久久| 午夜亚洲福利| 国产婷婷色一区二区三区四区| 亚洲天堂成人在线视频| 亚洲精品一区二区三区在线观看| 久久人人九九| 尤物视频一区二区| 玖玖在线精品| 久久综合给合久久狠狠狠97色69| 国产亚洲综合在线| 久久精品一区二区国产| 校园春色国产精品| 国产亚洲综合在线| 久久久久久久999精品视频| 中文国产成人精品久久一| 欧美日韩在线观看视频| 中文在线资源观看视频网站免费不卡| 亚洲激情第一页| 欧美日本二区| 亚洲欧美国产精品va在线观看| 国产精品99久久99久久久二8 | 在线观看日韩专区| 久久先锋影音av| 久久久久久亚洲精品不卡4k岛国| 激情六月婷婷久久| 欧美大片在线观看| 欧美激情视频给我| 亚洲欧美激情一区二区| 欧美一级淫片aaaaaaa视频| 好吊视频一区二区三区四区| 久久免费黄色| 欧美成人免费在线观看| 亚洲欧美国产日韩天堂区| 欧美亚洲免费| 亚洲人成人99网站| 中国女人久久久| 精品成人国产| 99视频超级精品| 精品51国产黑色丝袜高跟鞋| 亚洲欧洲另类国产综合| 国产伦精品一区二区三区视频黑人| 久久欧美肥婆一二区| 性欧美精品高清| 蜜桃伊人久久| 国产在线精品成人一区二区三区| 麻豆九一精品爱看视频在线观看免费| 久久久久久久久伊人| 亚洲最新合集| 久久久久国产一区二区三区| 一本久久综合亚洲鲁鲁| 欧美一区二区三区在线视频| 99国产精品视频免费观看| 欧美一区二区三区在线| 一个色综合av| 玖玖在线精品| 久久九九精品99国产精品| 欧美另类videos死尸| 久久免费黄色| 国产精品制服诱惑| 亚洲美女在线国产| 亚洲国产精品一区制服丝袜| 亚洲一区在线播放| 亚洲最快最全在线视频| 久久亚洲精品一区二区| 欧美亚洲一区二区在线观看| 欧美乱人伦中文字幕在线| 美国十次成人| 国产日韩精品久久久| 99re8这里有精品热视频免费 | 欧美va亚洲va日韩∨a综合色| 欧美在线一区二区| 国产精品久久久久久久久久久久 | 亚洲伊人久久综合| av成人黄色| 欧美11—12娇小xxxx| 老色鬼精品视频在线观看播放| 国产精品久久99| 一本一本大道香蕉久在线精品| 亚洲欧洲日本mm| 麻豆av福利av久久av| 欧美成人性生活| 亚洲第一二三四五区| 久久久久久久精| 久久人人97超碰国产公开结果| 国产模特精品视频久久久久| 国产精品99久久久久久久女警| 国产精品99久久不卡二区| 欧美成人精品1314www| 欧美激情第六页| 亚洲欧洲中文日韩久久av乱码| 欧美电影打屁股sp| 亚洲人体影院| 亚洲天堂av图片| 国产精品入口福利| 欧美一区二区三区四区高清 | 亚洲网站在线| 午夜精品成人在线视频| 国产精品亚洲网站| 午夜精品一区二区三区电影天堂 | 欧美激情第一页xxx| 欧美一区二区三区在线播放| 欧美在线观看日本一区| 国产欧美精品一区二区色综合| 亚洲欧美日韩在线综合| 久久久久久久综合狠狠综合| 经典三级久久| 欧美黄色精品| 亚洲一区二区免费| 久久久精品一品道一区| 伊人精品在线| 欧美精品亚洲精品| 亚洲女人天堂成人av在线| 久久一二三四| 中文精品视频| 国产一区欧美| 欧美精品在线观看一区二区| 中文日韩电影网站| 噜噜噜躁狠狠躁狠狠精品视频| 亚洲精品综合| 国产丝袜一区二区| 欧美欧美在线| 久久精品99国产精品| 亚洲精品免费网站| 久久精品二区三区| 一本久久综合| 亚洲丁香婷深爱综合| 国产精品久久久久免费a∨大胸 | 欧美日韩免费高清一区色橹橹| 亚洲自拍高清| 亚洲国产精品第一区二区| 亚洲在线网站| 亚洲国产成人91精品| 国产精品久久久一本精品| 久久人人爽人人爽爽久久| 一区二区三区四区蜜桃| 欧美成人精品| 久久久99爱| 亚洲一区自拍| 亚洲精品国产拍免费91在线| 国产精品一区=区| 欧美日韩国产色站一区二区三区| 欧美亚洲视频| 亚洲视屏在线播放| 亚洲精品一区二区三区四区高清| 久久久久久久久久久成人| 亚洲影院一区| 在线亚洲精品| 99精品免费视频| 91久久久国产精品| 狠狠干狠狠久久| 国产欧美精品一区| 国产精品乱人伦一区二区 |