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

            關(guān)于工作和讀書的筆記

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              47 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

            留言簿(14)

            搜索

            •  

            積分與排名

            • 積分 - 53106
            • 排名 - 433

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

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



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

            現(xiàn)在把24課的內(nèi)容升級(jí)為模板,就有了下面的代碼:
            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;
            //..
            }

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

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

            于是終于到了最后一步:關(guān)掉OPTION1, OPTION2,打開(kāi)OPTION3。
            無(wú)可奈何中我們把友元函數(shù)的定義放到了模板類的定義中,相當(dāng)于把這個(gè)“朋友”拉上了船,只要我被定義了,你就一定會(huì)被定義。同甘共苦,才算是真的朋友@#¥%
            于是編譯通過(guò)了,因?yàn)榫幾g器看到了如下的函數(shù)被聲明
            const?Rationalint>?operator?*?(?const?Rationalint>&?lhs,?const?Rationalint>&?rhs?);
            于是鏈接通過(guò)了,因?yàn)殡S著Rational對(duì)象的定義,上面的函數(shù)也實(shí)際被定義了出來(lái),編譯器很高興,結(jié)果很完美。

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

            posted on 2010-05-01 11:53 Justin.H 閱讀(1725) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Effective C++ 炒冷飯
            久久99精品国产麻豆宅宅| 久久亚洲熟女cc98cm| 久久成人影院精品777| 成人a毛片久久免费播放| 亚洲国产综合久久天堂| 久久久久亚洲av无码专区导航| 精品久久一区二区| 亚洲欧美国产日韩综合久久| 69久久精品无码一区二区| 日韩久久久久中文字幕人妻| 国产成人精品免费久久久久| 亚洲精品国产第一综合99久久| 国内精品久久国产大陆| 亚洲精品乱码久久久久久蜜桃图片| 久久精品9988| 久久久精品2019免费观看| 国产69精品久久久久观看软件| 日韩亚洲欧美久久久www综合网 | 亚洲狠狠综合久久| 少妇人妻综合久久中文字幕| 精品久久人人爽天天玩人人妻| 亚洲精品无码久久久久久| 亚洲国产成人精品无码久久久久久综合| 亚洲国产成人乱码精品女人久久久不卡 | 青青国产成人久久91网| 久久久久人妻精品一区| 无码任你躁久久久久久老妇App| 亚洲精品高清国产一久久| 久久国产精品一区二区| 丁香狠狠色婷婷久久综合| 色综合久久久久综合体桃花网| 一级a性色生活片久久无| 久久这里有精品视频| 久久成人精品| 亚洲国产成人久久精品99| 亚洲?V乱码久久精品蜜桃| 欧美与黑人午夜性猛交久久久| 久久久久18| 久久只有这精品99| 欧美熟妇另类久久久久久不卡| 亚洲人成网亚洲欧洲无码久久 |