• <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++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              47 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

            留言簿(14)

            搜索

            •  

            積分與排名

            • 積分 - 52490
            • 排名 - 433

            最新評論

            閱讀排行榜

            評論排行榜

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



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

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

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

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

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

            posted on 2010-05-01 11:53 Justin.H 閱讀(1709) 評論(0)  編輯 收藏 引用 所屬分類: Effective C++ 炒冷飯
            国产高潮国产高潮久久久| 久久综合久久久| 亚洲综合伊人久久大杳蕉| 午夜精品久久久久久毛片| 成人久久综合网| 中文精品久久久久人妻| 亚洲AV日韩精品久久久久| 国产99久久久国产精免费| 久久精品卫校国产小美女| 色偷偷888欧美精品久久久| 中文精品99久久国产 | 亚洲精品久久久www| 久久久久久九九99精品| 久久久久亚洲av毛片大| 久久久久亚洲av无码专区导航| 国产午夜精品久久久久九九| 亚洲人成精品久久久久| 久久人妻少妇嫩草AV蜜桃| 潮喷大喷水系列无码久久精品| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区| 伊人久久大香线蕉综合Av | 久久精品人人槡人妻人人玩AV| 久久成人18免费网站| 国内精品人妻无码久久久影院| 思思久久好好热精品国产| 亚洲国产精品一区二区久久| 性欧美丰满熟妇XXXX性久久久 | 色婷婷综合久久久中文字幕| 久久精品国产一区二区电影| 国产成人精品久久综合| 精品久久久久久| 国产精品一久久香蕉产线看| 久久综合给久久狠狠97色| 精品久久久久成人码免费动漫| 亚洲国产成人精品女人久久久 | 99国产欧美久久久精品蜜芽| 久久久久久国产精品无码下载 | 亚洲乱码中文字幕久久孕妇黑人| 色狠狠久久综合网| 麻豆av久久av盛宴av| 亚洲国产精品无码成人片久久 |