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

            搜索

            •  

            積分與排名

            • 積分 - 52710
            • 排名 - 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 閱讀(1716) 評論(0)  編輯 收藏 引用 所屬分類: Effective C++ 炒冷飯
            伊人色综合久久天天人守人婷| 亚洲伊人久久成综合人影院 | 99久久国产综合精品女同图片| 亚洲婷婷国产精品电影人久久| 2021最新久久久视精品爱| 久久久久亚洲AV无码专区首JN| 久久婷婷五月综合色高清| 久久精品国产秦先生| 久久男人AV资源网站| 亚洲国产欧洲综合997久久| 久久无码人妻一区二区三区午夜| 欧美亚洲另类久久综合| 无码任你躁久久久久久| 69久久夜色精品国产69| 久久国产欧美日韩精品免费| 97精品久久天干天天天按摩| 欧美伊人久久大香线蕉综合69| 久久午夜伦鲁片免费无码| 伊色综合久久之综合久久| 久久被窝电影亚洲爽爽爽| 久久久久亚洲AV无码观看| 草草久久久无码国产专区| 性欧美丰满熟妇XXXX性久久久 | 欧洲国产伦久久久久久久| 国产精品久久久久9999高清| 精品久久久久久久国产潘金莲| 国产精品热久久毛片| 韩国无遮挡三级久久| 久久精品蜜芽亚洲国产AV| 少妇熟女久久综合网色欲| 久久久久亚洲AV无码专区网站| 国产欧美久久一区二区| 久久国产精品成人片免费| 久久精品国产99久久久古代| 欧美一级久久久久久久大| 久久国产精品偷99| 精品久久久久久久久久中文字幕 | yy6080久久| 久久精品国产亚洲av麻豆图片| 伊人色综合久久天天网| 合区精品久久久中文字幕一区 |