• <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>

            Note of Justin

            關于工作和讀書的筆記

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              47 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

            留言簿(14)

            搜索

            •  

            積分與排名

            • 積分 - 52498
            • 排名 - 433

            最新評論

            閱讀排行榜

            評論排行榜

            [原創文章歡迎轉載,但請保留作者信息]
            Justin 于 2010-05-01



            大師的課上到46堂了,今天課前要求復習一下24課的內容。
            如果你懶得自己去看,這里大概提一下:24課說的是如果在實際調 用中,某個函數的任何一個參數都有可能是其他類型數據通過“類型轉換”轉換過來的,這個函數最好是寫成非成員函數。(哪 怕回去24節看,掃一遍書上的例子也知道是什么意思了)

            現在把24課的內容升級為模板,就有了下面的代碼:
            template?typename?T>
            class?Rational?{
            ???
            public:
            ??????Rational(
            const?T&?num?=?0,?const?T&?denom?=?1)
            ??????{
            ?????????_numerator?
            =?num;
            ?????????_denominator?
            =?denom;
            ??????}
            #if?OPTION2
            ??????friend?
            const?Rational?operator*(const?Rational&?lhs,?const?Rational&?rhs);
            #endif
            #if?OPTION3
            friend?
            const?Rational?operator?*?(const?Rational&?lhs,?const?Rational&?rhs)
            {
            ???
            return?Rational(lhs.numerator()?*?rhs.numerator(),?lhs.denominator()?*?rhs.denominator());
            }
            #endif

            ??????
            const?T?numerator()?const?{?return?_numerator;?}
            ??????
            const?T?denominator()?const?{?return?_denominator;?}

            ???
            private:
            ??????T?_numerator;
            ??????T?_denominator;
            ??????
            //..
            };
            #if?OPTION1?||?OPTION2
            template?
            typename?T>
            const?RationalT>?operator?*?(const?RationalT>&?lhs,?const?RationalT>&?rhs)
            {
            ???
            return?RationalT>?(lhs.numerator()?*?rhs.numerator(),?lhs.denominator()?*?rhs.denominator());
            }
            #endif

            int?main(void)
            {
            ???Rational
            int>?oneFourth(1,?4);
            ???Rational
            int>?result;
            ???result?
            =?oneFourth?*2;
            //..
            }

            當OPTION1為真時,就是item24中的實現方法:用非成員函數來使得所有的參數都可以接受類型轉換。
            但是編譯不能通過。這說明模板C++的世界是不一樣的: 對于以上代碼的非模板版本,編譯器只需要關心哪個函數可以調用就可以了;
            而引入模板后, 由于一個模板函數可以有無數個實例,編譯器首先要知道的是應該生成哪一個實例,然后才是調用。
            OPTION1為真時的代碼,這個模板函數在編譯時期就會碰到問題:模板參數無法確定。本來說好了接受一個Rational& 類型參數的,現在(在main()里 的第三行)給我一個int,叫我怎么辦?
            如果我是編譯器的話我會認為這種情況下模板參數T就是int,于是實例化下面的函數
            const?Rationalint>?operator?*?(?const?Rationalint>&?lhs,?const?Rationalint>&?rhs?);
            該函數可以通過隱式類型轉換接受int類型的參數,順利完成任務!
            可是,編譯器很笨,做不到。

            于是可以考慮關掉OPTION1,打開OPTION2:把模板非成員函數當成友元+非成員+模板函數。為什么需要友元呢?
            OPTION1失敗的原因是編譯器無法生成合適的模板函數實例,它認為沒有合適的實例可以調用,于是編譯失敗。
            如果模板函數變成友元,編譯器首先看到有Rational對象定義出來(main()中第二第三行),就認為會有一個下面的函數 作為友元:
            const?Rationalint>?operator?*?(?const?Rationalint>&?lhs,?const?Rationalint>&?rhs?);
            當然,它不會在編譯階段去計較是不是真的有這么一個函數實例(友元嘛,就是朋友的東東,朋友說有,我就相信有咯~)
            于是,編譯通過!
            可是編譯通過后,鏈接卻出了問題:到鏈接階段才發現,這個“朋友”的模板函數根本沒有實例可以調用?。ㄟ€是一樣的問題, 沒有可以接受int參數的版本。朋友也不可靠啊……)
            問題就在類外部的友元模板函數僅僅在類中得到了聲明(declaration)而沒有被定義(definition)。對于模板函數,使用者既需要聲明,又需要定義。(比如說 vector v,事實上已經通過制定模板參數完成了模板函數的定義。)

            于是終于到了最后一步:關掉OPTION1, OPTION2,打開OPTION3。
            無可奈何中我們把友元函數的定義放到了模板類的定義中,相當于把這個“朋友”拉上了船,只要我被定義了,你就一定會被定義。同甘共苦,才算是真的朋友@#¥%
            于是編譯通過了,因為編譯器看到了如下的函數被聲明
            const?Rationalint>?operator?*?(?const?Rationalint>&?lhs,?const?Rationalint>&?rhs?);
            于是鏈接通過了,因為隨著Rational對象的定義,上面的函數也實際被定義了出來,編譯器很高興,結果很完美。

            事實上這次的讀書筆記記了兩次,當我重新看第一次的筆記時竟然不知所云,于是重新看了一次,也修改了第一版的筆記成為 第二版。
            看來,模板真的很能搞……

            posted on 2010-05-01 11:53 Justin.H 閱讀(1710) 評論(0)  編輯 收藏 引用 所屬分類: Effective C++ 炒冷飯
            国产国产成人久久精品| 久久久久久久亚洲Av无码| 日本精品久久久中文字幕| 久久久久久久久久免免费精品| 亚洲国产精品一区二区三区久久| 中文无码久久精品| 久久精品免费网站网| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 午夜精品久久久久久99热| 曰曰摸天天摸人人看久久久| 久久久久久曰本AV免费免费| 国产精品无码久久四虎| 亚洲欧美久久久久9999| 久久久婷婷五月亚洲97号色| 久久国产成人亚洲精品影院| 国产成人精品久久亚洲高清不卡 | 久久国产精品免费一区| 久久久女人与动物群交毛片| 久久黄视频| 久久久久久无码Av成人影院| 亚洲精品tv久久久久| 国产综合久久久久| 97久久超碰成人精品网站| 久久夜色精品国产欧美乱| 久久午夜夜伦鲁鲁片免费无码影视| 久久五月精品中文字幕| 久久综合一区二区无码| 国产精品天天影视久久综合网| 国产69精品久久久久观看软件 | 亚洲?V乱码久久精品蜜桃| 久久久久国产精品熟女影院| 亚洲伊人久久综合中文成人网| 久久无码人妻一区二区三区午夜| 久久综合色区| 久久久精品国产亚洲成人满18免费网站| 久久天天躁狠狠躁夜夜96流白浆| 99久久这里只精品国产免费 | 国内精品久久久久影院薰衣草| 久久露脸国产精品| 久久丝袜精品中文字幕| 国产毛片久久久久久国产毛片|