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

天行健 君子當自強而不息

【ZT】C++批判(4)


函數重載

 C++允許在參數類型不同的前提下重載函數。重載的函數與具有多態性的函數(即虛函數)不同處在于:調用正確的被重載函數實體是在編譯期間就被決定了的;而對于具有多態性的函數來說,是通過運行期間的動態綁定來調用我們想調用的那個函數實體。多態性是通過重定義(或重寫)這種方式達成的。請不要被重載 (overloading)和重寫(overriding)所迷惑。重載是發生在兩個或者是更多的函數具有相同的名字的情況下。區分它們的辦法是通過檢測它們的參數個數或者類型來實現的。重載與CLOS中的多重分發(multiple dispatching)不同,對于參數的多重分發是在運行期間多態完成的。
 
 【Reade 89】中指出了重載與多態之間的不同。重載意味著在相同的上下文中使用相同的名字代替出不同的函數實體(它們之間具有完全不同的定義和參數類型)。多態則只具有一個定義體,并且所有的類型都是由一種最基本的類型派生出的子類型。C. Strachey指出,多態是一種參數化的多態,而重載則是一種特殊的多態。用以判斷不同的重載函數的機制就是函數標示(function signature)。
 
 重載在下面的例子中顯得很有用:

 max( int, int )
 max( real, real )

 
  這將確保相對于類型int和real的最佳的max函數實體被調用。但是,面向對象的程序設計為該函數提供了一個變量,對象本身被被當作一個隱藏的參數傳遞給了函數(在C++中,我們把它稱為this)。由于這樣,在面向對象的概念中又隱式地包含了一種對等的但卻更有更多限制的形式。對于上述討論的一個簡單例子如下:

 int i, j;
 real r, s;
 i.max(j);
 r.max(s);

 
 但如果我們這樣寫:i.max(r),或是r.max(j),編譯器將會告訴我們在這其中存在著類型不匹配的錯誤。當然,通過重載運算符的操作,這樣的行為是可以被更好地表達如下:

 i max j 或者 r max s

 但是,min和max都是特殊的函數,它們可以接受兩個或者更多的同一類型的參數,并且還可以作用在任意長度的數組上。因此,在Eiffel中,對于這種情況最常見的代碼形式看起來就像這樣:

 il:COMPARABLE_LIST[INTEGER]
 rl:COMPARABLE_LIST[REAL]
 
 i := il.max
 r := rl.max

 
  上面的例子顯示,面向對象的編程典范(paradigm),特別是和范型化(genericity)結合在一起時,也可以達到函數重載的效果而不需要C+ +中的函數重載那樣的聲明形式。然而是C++使得這種概念更加一般化。C++這樣作的好處在于,我們可以通過不止一個的參數來達到重載的目的,而不是僅使用一個隱藏的當前對象作為參數這樣的形式。
 
 另外一個我們需要考慮的因素是,決定(resolved)哪個重載函數被調用是在編譯階段完成的事情,但對于重寫來說則推后到了運行期間。這樣看起來好像重載能夠使我們獲得更多性能上的好處。然而,在全局分析的過程中編譯器可以檢測函數min 和max是否處在繼承的最末端,然后就可以直接的調用它們(如果是的話)。這也就是說,編譯器檢查到了對象i和r,然后分析對應于它們的max函數,發現在這種情況下沒有任何多態性被包含在內,于是就為上面的語句產生了直接調用max的目標代碼。與此相反的是,如果對象n被定義為一個NUMBER, NUMBER又提供一個抽象的max函數聲明(我們所用的REAL.max和INTERGER.max都是從它繼承來的),那么編譯器將會為此產生動態綁定的代碼。這是因為n既可能是INTEGER,也有可能是REAL。
 
 現在你是不是覺得C++的這種方法(即通過提供不同的參數來實現函數的重載)很有用?不過你還必須明白,面向對象的程序設計對此有著種種的限制,存在著許多的規則。C++是通過指定參數必須與基類相符合的方式實現它的。傳入函數中的參數只能是基類,或是基類的派生類。

例如:

 A.f( B someB )
 class B ...;
 class D : public B ...;
 A a;
 D d;
 a.f( d );


 其中d必須與類'B'相符,編譯器會檢測這些。
 
  通過不同的函數簽名(signature)來實現函數重載的另一種可行的方法是,給不同的函數以不同的名字,以此來使得它們的簽名不同。我們應該使用名字來作為區分不同實體(entities)的基礎。編譯器可以交叉檢測我們提供的實參是否符合于指定的函數需要的形參。這同時也導致了軟件更好的自記錄(self-document)。從相似的名字選擇出一個給指定的實體通常都不會很容易,但它的好處確實值得我們這樣去做。
 
 [Wiener95]中提供了一個例子用以展示重載虛擬函數可能出現的問題:

 class Parent
 {
  public:
   virutal int doIt( int v )
   {
    return v * v;
   }
 };
 
 class Child: public Parent
 {
  public:
   int doIt( int v, int av = 20 )
   {
    return v * av;
   }
 };
 
 int main()
 {
  int i;
  Parent *p = new Child();
  i = p->doIt(3);
  return 0;
 }

 
 當程序執行完后i會等于多少呢?有人可能會認為是60,然而結果卻是9。這是因為在Child中doIt的簽名與在Parent中的不一致,它并沒有重寫Parent中的doIt,而僅僅是重載了它,在這種情況下,缺省值沒有任何作用。

再來看看這個例子,絕對讓你抓狂,猜猜看輸出的i和j值是多少?

#include <stdio.h>

class PARENT
{
public:
    virtual int doIt( int v, int av = 10 )
    {
         return v * v;
    }
};

class CHILD : public PARENT
{
public:
    int doIt( int v, int av = 20 )
    {
         return v * av;
    }
};

int main()
{
    PARENT *p = new CHILD();

    int i = p->doIt(3);
    printf("i = %d\n", i);

    CHILD* q = new CHILD();

    int j = q->doIt(3);
    printf("j = %d\n", j);

    return 0;
}

 
 Java也提供了方法重載,不同的方法可以擁有同樣的名字及不同的簽名。
 
 在Eiffel中沒有引入新的技術,而是使用范型化、繼承及重定義等。Eiffel提供了協變式的簽名方式,這意味著在子類的函數中不需要完全符合父類中的簽名,但是通過Eiffel的強類型檢測技術可以使得它們彼此相匹配。
 

posted on 2007-09-27 13:24 lovedday 閱讀(404) 評論(0)  編輯 收藏 引用 所屬分類: ▲ C++ Program

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国一区二区在线观看| 亚洲国产国产亚洲一二三| 99精品视频免费观看视频| 美女精品在线观看| 久久夜色精品国产欧美乱| 1000部国产精品成人观看| 亚洲成色999久久网站| 久久综合狠狠| 亚洲第一色中文字幕| 欧美国产丝袜视频| 欧美日韩亚洲综合一区| 午夜亚洲影视| 久久久亚洲人| 一本久久综合亚洲鲁鲁五月天| 一区二区不卡在线视频 午夜欧美不卡在 | 激情综合色综合久久| 久久综合中文色婷婷| 欧美成人伊人久久综合网| 在线性视频日韩欧美| 性欧美xxxx大乳国产app| 亚洲国产精品久久久久| 亚洲黄网站黄| 国产精品捆绑调教| 女主播福利一区| 欧美色欧美亚洲高清在线视频| 欧美一区三区二区在线观看| 另类春色校园亚洲| 亚洲永久免费视频| 久久在精品线影院精品国产| 亚洲影院免费| 美女脱光内衣内裤视频久久影院 | 国产欧美日韩亚洲一区二区三区| 久久综合九色欧美综合狠狠| 欧美日韩精品免费在线观看视频| 久久精品国产亚洲一区二区三区| 欧美人体xx| 久久久久久婷| 国产精品国产三级国产专播精品人| 久久天堂成人| 国产精品久久久久秋霞鲁丝| 亚洲第一中文字幕在线观看| 国产日韩视频| 亚洲视频www| 亚洲日韩成人| 久久精品麻豆| 欧美在线视频观看| 欧美日本免费一区二区三区| 美女免费视频一区| 国产日韩精品在线| 亚洲视频播放| 中文在线资源观看网站视频免费不卡| 久久久久**毛片大全| 香蕉乱码成人久久天堂爱免费| 欧美国产91| 欧美大尺度在线观看| 国内精品模特av私拍在线观看| 一区二区三区四区五区视频| 91久久精品美女高潮| 久久精品国产2020观看福利| 久久精品国产69国产精品亚洲| 欧美午夜精品久久久久免费视| 亚洲国产精品第一区二区| 精品动漫3d一区二区三区免费| 亚洲综合国产| 欧美影院成年免费版| 国产精品一区免费视频| 99视频在线观看一区三区| 99热精品在线观看| 欧美激情区在线播放| 最新亚洲一区| 日韩视频二区| 欧美三级视频在线观看| 亚洲美女啪啪| 亚洲在线日韩| 国产午夜精品福利| 久久久久久婷| 欧美激情综合色| 日韩亚洲国产精品| 欧美日韩无遮挡| 亚洲一区免费看| 久久精品亚洲精品国产欧美kt∨| 国产欧美69| 久久精品视频99| 欧美激情视频在线免费观看 欧美视频免费一 | 欧美亚洲视频一区二区| 久久精品一本| 亚洲电影自拍| 欧美区在线播放| 亚洲在线中文字幕| 久久久久久久国产| 亚洲日本在线观看| 国产精品r级在线| 欧美在线观看一区二区| 欧美a级片网站| 亚洲曰本av电影| 国内精品久久久久久久97牛牛| 久久在线视频| 一级日韩一区在线观看| 久久精选视频| 一本一本a久久| 国产婷婷一区二区| 欧美精品18| 午夜国产精品影院在线观看| 欧美 日韩 国产一区二区在线视频| 日韩亚洲欧美一区| 国产一区在线播放| 欧美激情中文不卡| 欧美在线视频免费播放| 亚洲狼人综合| 久久久亚洲欧洲日产国码αv| 日韩视频在线免费| 国产欧美综合一区二区三区| 欧美激情综合网| 久久国产视频网| 亚洲午夜一区二区三区| 欧美不卡三区| 欧美在线影院| 一区二区福利| 亚洲人永久免费| 一区在线播放视频| 国产精品日韩专区| 欧美日韩日日骚| 欧美成人精品在线| 久久精品夜色噜噜亚洲a∨| 亚洲网址在线| 亚洲精品一区二区三区在线观看| 麻豆精品一区二区综合av | 狠狠入ady亚洲精品经典电影| 欧美日韩免费看| 欧美91福利在线观看| 欧美在线电影| 亚洲欧美日韩区| 亚洲自拍偷拍视频| 中文在线一区| 日韩五码在线| 亚洲久久视频| 亚洲黄色有码视频| 亚洲成在人线av| 欧美a级片网站| 美日韩精品视频| 久久综合狠狠综合久久综合88| 久久不射中文字幕| 欧美一级艳片视频免费观看| 午夜精品久久久久99热蜜桃导演| 在线视频你懂得一区二区三区| 亚洲日韩成人| 夜夜躁日日躁狠狠久久88av| 亚洲国产精品久久人人爱蜜臀| 亚洲福利视频免费观看| 在线播放中文一区| 亚洲福利视频二区| 亚洲人成人99网站| 日韩视频一区二区在线观看 | 一个色综合av| 亚洲女人天堂av| 欧美一区影院| 久久亚洲精品一区二区| 久久综合激情| 欧美日韩成人在线| 国产精品高潮呻吟久久av无限| 国产精品乱码一区二区三区| 国产精品色婷婷| 伊人久久噜噜噜躁狠狠躁| 亚洲激情成人在线| 日韩天堂在线观看| 亚洲欧美日韩成人| 久久久天天操| 亚洲大胆人体视频| 亚洲美女av网站| 欧美一级片久久久久久久| 老司机午夜精品| 欧美视频1区| 黄色另类av| 99热在线精品观看| 久久av一区二区三区亚洲| 美女性感视频久久久| 亚洲精品日韩久久| 欧美在线视频导航| 欧美激情一区二区三区蜜桃视频| 国产精品免费aⅴ片在线观看| 黄色成人av网| 亚洲一区二区三区四区在线观看 | 欧美xxxx在线观看| 中文国产一区| 久久一综合视频| 欧美日韩和欧美的一区二区| 国产亚洲欧美一区| 日韩亚洲欧美中文三级| 久久久久久久波多野高潮日日| 亚洲激情校园春色| 欧美怡红院视频| 欧美四级在线观看| 亚洲高清免费视频| 欧美在现视频| 亚洲毛片网站| 欧美成人精品一区| 国产综合av| 午夜亚洲福利在线老司机| 亚洲激情视频在线| 久久永久免费|