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

洛譯小筑

別來無恙,我的老友…
隨筆 - 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>
            亚洲日本va在线观看| 欧美在线观看一区| 美女视频网站黄色亚洲| 欧美一区二区三区在线观看视频| 国产精品视频一| 久久精品最新地址| 久久另类ts人妖一区二区| 亚洲黄色一区| 9久re热视频在线精品| 国产欧美日本一区二区三区| 久久久久久久久蜜桃| 欧美黑人在线播放| 亚洲女同精品视频| 久久网站热最新地址| 亚洲免费黄色| 亚洲免费在线精品一区| 黄色成人免费网站| 亚洲精品美女免费| 国产亚洲激情在线| 欧美激情一二区| 国产精品男女猛烈高潮激情| 久热国产精品视频| 欧美色另类天堂2015| 久久影音先锋| 欧美午夜不卡视频| 欧美va亚洲va日韩∨a综合色| 欧美日韩不卡| 久久永久免费| 国产精品亚洲综合一区在线观看| 老司机午夜精品| 国产精品黄视频| 性欧美大战久久久久久久久| 亚洲国产mv| 亚洲一区在线直播| 亚洲美女毛片| 久久精品亚洲| 香蕉成人啪国产精品视频综合网| 欧美 日韩 国产 一区| 久久久7777| 国产精品福利在线观看| 亚洲国产国产亚洲一二三| 国产一级一区二区| 亚洲一区二区精品在线| 99国产精品久久久久久久成人热| 久久不见久久见免费视频1| 亚洲一区亚洲二区| 欧美国产极速在线| 欧美激情2020午夜免费观看| 国产欧美日韩免费看aⅴ视频| 99视频一区二区三区| 亚洲精品一区在线| 免播放器亚洲| 欧美刺激午夜性久久久久久久| 国产欧美一区二区精品婷婷| 亚洲网在线观看| 亚洲一区二区三区四区在线观看| 欧美jizzhd精品欧美巨大免费| 久久亚洲私人国产精品va| 国产日韩欧美不卡在线| 亚洲一区二区三区精品视频| 中日韩视频在线观看| 欧美日本在线视频| 亚洲精品欧美日韩| 亚洲少妇诱惑| 国产精品ⅴa在线观看h| 一区二区三区免费网站| 亚洲图片欧洲图片av| 国产精品国产三级欧美二区| 一区二区三区日韩精品视频| 亚洲欧美日韩在线播放| 国产精品萝li| 午夜精品久久久久久久久久久| 欧美一区二区精品久久911| 国产乱码精品一区二区三区忘忧草 | 久久成人在线| 久久久一本精品99久久精品66| 国产日韩精品一区二区三区在线| 午夜精品一区二区三区四区 | 91久久精品国产91久久| 亚洲精品日韩激情在线电影| 欧美精品色综合| 国产精品99久久久久久有的能看 | 欧美影院在线| 国内成+人亚洲| 狂野欧美一区| 99在线观看免费视频精品观看| 亚洲女性裸体视频| 狠狠色丁香久久综合频道| 久久综合一区| 在线中文字幕一区| 久久一区二区精品| 亚洲美女中文字幕| 日韩一级片网址| 久久手机精品视频| 亚洲三级影院| 久久av一区二区三区| 1769国内精品视频在线播放| 欧美日韩精品在线| 久久久www成人免费无遮挡大片| 亚洲高清免费在线| 欧美亚洲视频| 日韩午夜精品| 国内精品久久久久久久影视麻豆| 欧美大片专区| 久久av一区二区三区| 亚洲激情在线播放| 欧美中在线观看| 99国产麻豆精品| 国内一区二区在线视频观看 | 亚洲一区免费| 亚洲欧洲三级电影| 另类av一区二区| 午夜精品久久久久99热蜜桃导演| 亚洲国产第一页| 国产亚洲人成a一在线v站| 欧美日韩国产区| 裸体一区二区三区| 欧美一区二区视频97| 一区二区电影免费观看| 亚洲高清在线播放| 老司机精品视频一区二区三区| 亚洲一区免费网站| 日韩网站在线观看| 亚洲国产精品99久久久久久久久| 国产精品一区在线播放| 欧美视频手机在线| 欧美美女视频| 欧美韩国日本综合| 乱码第一页成人| 久久香蕉国产线看观看网| 先锋影音一区二区三区| 亚洲在线黄色| 中日韩午夜理伦电影免费| 91久久精品国产91久久| 亚洲电影免费观看高清| 欧美成人中文字幕在线| 老鸭窝毛片一区二区三区| 久久伊人精品天天| 老鸭窝91久久精品色噜噜导演| 久久久国际精品| 久久一区二区三区国产精品| 久久欧美中文字幕| 老司机午夜精品视频| 美国成人毛片| 欧美成人免费在线| 亚洲国产精品电影在线观看| 亚洲国产精品视频一区| 亚洲国产精品成人一区二区| 亚洲成色999久久网站| 亚洲国产精品一区二区www在线| 欧美激情一区二区在线 | 亚洲欧美日韩精品久久奇米色影视 | 亚洲视频久久| 亚洲综合三区| 欧美怡红院视频一区二区三区| 欧美一区国产一区| 久久综合九色综合久99| 免费国产一区二区| 欧美人成在线视频| 欧美午夜精品一区| 国产老女人精品毛片久久| 好吊日精品视频| 在线综合亚洲欧美在线视频| 久久久精品动漫| 欧美成人免费播放| 亚洲日本中文字幕| 亚洲砖区区免费| 久久久亚洲国产美女国产盗摄| 久久久久88色偷偷免费| 欧美激情精品久久久久久蜜臀| 欧美日韩精品免费在线观看视频| 国产精品久久久久久久久婷婷 | aaa亚洲精品一二三区| 亚洲欧美韩国| 欧美成人精品三级在线观看| 日韩亚洲精品视频| 欧美一区二区在线免费播放| 欧美成人首页| 国产日韩欧美视频在线| 亚洲欧洲精品一区二区三区不卡 | 国产欧美日韩视频一区二区三区 | 亚洲日韩欧美一区二区在线| 亚洲欧美中日韩| 欧美国产日韩一区二区在线观看| av成人激情| 免费观看国产成人| 国产欧美视频一区二区三区| 亚洲精品日韩激情在线电影| 性高湖久久久久久久久| 亚洲国产高清视频| 欧美影院在线| 欧美性猛交视频| 亚洲精品国产品国语在线app| 欧美在线观看视频在线| 亚洲日本成人网| 久久在线播放| 国产一区二区三区精品欧美日韩一区二区三区 | 亚洲欧美日韩精品综合在线观看 | 免费在线观看精品| 韩国一区二区在线观看|