• <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>
            萬(wàn)星星@豌豆莢 歡迎加入我們
            一個(gè)吃軟飯的男人!!!!!我只想寫(xiě)程序####
            微博:http://weibo.com/wanlianwen
            posts - 172,  comments - 1253,  trackbacks - 0
            獨(dú)自一人苦學(xué)模板,實(shí)在郁悶,翻譯e文逼迫自己學(xué)習(xí):(全部寫(xiě)完后整理)

            8.4 友元
            聲明友元的思想其實(shí)很簡(jiǎn)單:標(biāo)識(shí)一個(gè)類(lèi)或者函數(shù),對(duì)于將其聲明為友元所在的類(lèi)具有某種特權(quán)。但是在以下兩個(gè)方面,問(wèn)題似乎有點(diǎn)復(fù)雜:
            1、一個(gè)友元聲明只能是一個(gè)實(shí)體的唯一聲明(注:我還沒(méi)理解,不能解釋?zhuān)?br />2、友元函數(shù)聲明的同時(shí)可以定義。

            友元類(lèi)在聲明的時(shí)候不允許定義,所以一般不會(huì)有問(wèn)題。在模板情況下,唯一一點(diǎn)不同就是可以將類(lèi)模板的一個(gè)特定實(shí)例聲明為友元:
            template<typename?T>
            class?Node;

            template
            <typename?T>
            class?Tree{
            ????friend?
            class?Node<T>;
            ????…
            }
            ;
            注意:類(lèi)模板在被一個(gè)類(lèi)或者類(lèi)模板聲明為友元的時(shí)候必須是可見(jiàn)的,而對(duì)于普通的類(lèi)則沒(méi)有這種需求:
            template<typename?T>
            class?Tree{?
            ????friend?
            class?Factory;????????//?OK,?even?if?first?declaration?of?Factory
            ????friend?class?class?Node<T>;??//?ERROR?if?Node?isn't?visible
            }
            ;?

            8.4.1 友元函數(shù)
            函數(shù)模板的實(shí)例可以通過(guò)在函數(shù)名后面跟一對(duì)<>將其聲明為友元。<>里面可以包含模板參數(shù),如果編譯器可以推導(dǎo)出模板參數(shù),可以省略調(diào)模板參數(shù):
            template<typename?T1,?typename?T2>
            void?combine(T1,?T2);

            class?Mixer{
            ????friend?
            void?combine<>(int&,?int&);
            ????
            //?OK:?T1?=?int&,?T2?=?int&
            ????friend?void?combine<int,?int>(int,?int);
            ????
            //?OK:?T1?=?int,?T2?=?int
            ????friend?void?combine<char>(char,?int);
            ????
            //?OK:?T1?=?char?T2?=?int
            ????friend?void?combine<char>(char&,?int);
            ????
            //?ERROR:?doesn't?match?combine()?template
            ????friend?void?combine<>(long,?long)?{?}
            ????
            //?ERROR:?definition?not?allowed!
            }
            ;
            (注:在GCC下測(cè)試,VS2003不行)
            注意:我們可以對(duì)模板進(jìn)行專(zhuān)門(mén)化定義,但是不能對(duì)模板實(shí)例進(jìn)行定義,所以聲明模板實(shí)例為友元時(shí)不能定義。

            如果名字后面跟有<>,有2種可能:
            1、如果名字沒(méi)有限定詞(也就是前面沒(méi)有::),就不可能是模板實(shí)例。如果在聲明友元的地方?jīng)]有非模板函數(shù)匹配的話,就是函數(shù)的首次聲明,聲明同時(shí)可以定義。
            2、如果名字有限定詞,那么一定與前面聲明的函數(shù)或者模板函數(shù)有關(guān),在匹配的時(shí)候優(yōu)先選擇非函數(shù)模板而不是函數(shù)模板,然而在聲明的時(shí)候是不允許定義的。

            下面的例子總結(jié)了各種可能性:
            void?multiply?(void*);???//?ordinary?function?

            template?
            <typename?T>?
            void?multiply(T);????????//?function?template?

            class?Comrades?{?
            ????friend?
            void?multiply(int)?{}?
            ?????????????????????????
            //?defines?a?new?function?::multiply(int)?

            ????friend?
            void?::multiply(void*);?
            ?????????????????????????
            //?refers?to?the?ordinary?function?above;?
            ?????????????????????????
            //?not?to?the?multiply<void*>?instance?

            ????friend?
            void?::multiply(int);?
            ?????????????????????????
            //?refers?to?an?instance?of?the?template?

            ????friend?
            void?::multiply<double*>(double*);?
            ?????????????????????????
            //?qualified?names?can?also?have?angle?brackets?
            ?????????????????????????
            //?but?a?template?must?be?visible.?

            ????friend?
            void?::error()?{}?
            ?????????????????????????
            //?ERROR:?a?qualified?friend?cannot?be?a?definition?
            }
            ;?

            (注:在VS2003和規(guī)則復(fù)合,GCC上編譯完全通過(guò))

            前面例子我們討論了一般類(lèi)(相對(duì)于類(lèi)模板)里面的友元函數(shù),遵守的規(guī)則同樣適用于類(lèi)模板,但模板參數(shù)在確定友元函數(shù)的時(shí)候會(huì)起作用:
            template<typename?T>
            class?Node?{
            ????Node
            <T>*?allocate();
            }
            ;?

            template
            <typename?T>
            class?List?{
            ????friend?Node
            <T>*?Node<T>::allocate();
            }
            ;

            然而,當(dāng)友元函數(shù)在類(lèi)模板里面聲明并定義的時(shí)候會(huì)出現(xiàn)有趣的現(xiàn)象,因?yàn)槟0謇锩嫒魏螙|西在未實(shí)例化之前都只是聲明而沒(méi)有具現(xiàn)。考慮下面的例子:
            template<typename?T>
            class?Creator?{?
            ????friend?
            void?appear()?{??//?a?new?function?::appear(),?but?it?doesn't
            ????????…???????????????????//?exist?until?Creator?is?instantiated
            ????}

            }
            ;

            Creator
            <void>?miracle;??//?::appear()?is?created?at?this?point
            Creator<double>?oops;???//?ERROR:?::appear()?is?created?a?second?time!
            這個(gè)例子中模板的兩次實(shí)例化導(dǎo)致同一函數(shù)定義多次,違反了一次定義規(guī)則。

            所以對(duì)于上面的情況,我們必須確保類(lèi)模板的模板參數(shù)出現(xiàn)在聲明并定義的友元函數(shù)形參里面(除非想阻止多次實(shí)例化一個(gè)類(lèi)模板,這好像不太可能)。把這個(gè)規(guī)律運(yùn)用到前面那個(gè)例子:
            template<typename?T>
            class?Creator?{?
            ????friend?
            void?feed(Creator<T>*){??//?every?T?generates?a?different
            ????????????????????????????????????
            //?function?::feed()
            ????}

            }
            ;

            Creator
            <void>?one;?????//?generates?::feed(Creator<void>*)
            Creator<double>?two;???//?generates?::feed(Creator<double>*)
            這個(gè)例子中,Creator每個(gè)實(shí)例都生成不同的函數(shù)。注意這些函數(shù)是類(lèi)模板實(shí)例產(chǎn)生的,但函數(shù)本身并不是函數(shù)模板的實(shí)例,而是普通函數(shù)。
            還要注意這些函數(shù)體定義于類(lèi)中,默認(rèn)是內(nèi)聯(lián)的,所以在兩個(gè)翻譯單元產(chǎn)生相同的函數(shù)是沒(méi)有問(wèn)題的。(注:由于內(nèi)聯(lián)函數(shù)基于代碼替代技術(shù),所以一個(gè)函數(shù)定義所在的h文件被多次包含不會(huì)有問(wèn)題,內(nèi)聯(lián)函數(shù)在編譯器看來(lái)就是一段代碼。)

            8.4.2 友元模板
            一般情況我們都是把函數(shù)模板或者類(lèi)模板的某一實(shí)例聲明為友元,但把模板本身聲明為友元有時(shí)候也是非常有用的。這就需要所謂的模板友元,例如:
            class?Manager?{?
            ????template
            <typename?T>
            ????friend?
            class?Task;
            ????
            ????template
            <typename?T>
            ????friend?
            void?Schedule<T>::dispatch(Task<T>*);
            ????
            ????template
            <typename?T>
            ????friend?
            int?ticket()?{
            ????????
            return?++Manager::counter;
            ????}
            ?
            ????
            static?int?counter;
            }
            ;
            和普通友元函數(shù)一樣,沒(méi)有限定詞且名字后面沒(méi)有<>的函數(shù)模板在聲明為友元同時(shí)可以定義。
            聲明原始函數(shù)模板或者原始類(lèi)模板為友元的時(shí)候,所有相關(guān)的偏特化以及顯示特例化都自動(dòng)成為友元。
            (注:測(cè)試代碼
            class?Manager?{?
            ????template
            <typename?T>????//?firend?template
            ????friend?class?Task;
            private:
            ????
            int????_dat;
            }
            ;

            template
            <typename?T>
            class?Task?{
            }
            ;

            template
            <>
            class?Task<int>?{????????????//?specialization
            public:
            ????
            void?accessData()
            ????
            {
            ????????_manager._dat?
            =?0;????//?can?access?Manager's?private?data
            ????}

            private:
            ????Manager????_manager;
            }
            ;


            (本節(jié)完,汗...... 自己收獲不小)
            posted on 2006-04-06 23:48 萬(wàn)連文 閱讀(1122) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 模板
            簡(jiǎn)歷下載
            聯(lián)系我

            <2011年3月>
            272812345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(66)

            隨筆分類(lèi)

            隨筆檔案

            相冊(cè)

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            中文字幕无码久久精品青草| 久久强奷乱码老熟女网站| 久久亚洲国产最新网站| 久久久久久国产精品美女| 色综合久久中文色婷婷| 99久久精品费精品国产 | 久久免费视频1| 久久久久久一区国产精品| 久久精品嫩草影院| 国产伊人久久| 久久婷婷色香五月综合激情 | 精品久久久久久综合日本| 国产精品久久久久久久久| 国产福利电影一区二区三区,免费久久久久久久精 | 91久久国产视频| 久久人人爽人人爽人人片AV麻豆| 精品无码人妻久久久久久| 日本亚洲色大成网站WWW久久| 久久天天躁狠狠躁夜夜2020老熟妇| 久久婷婷人人澡人人| 久久久精品国产免大香伊| AV狠狠色丁香婷婷综合久久| 久久香蕉国产线看观看99 | 欧美777精品久久久久网| 日韩精品无码久久一区二区三| 久久久无码精品亚洲日韩蜜臀浪潮 | 久久黄视频| 亚洲综合伊人久久综合| 日本久久久久久中文字幕| 性欧美大战久久久久久久| 99久久国产宗和精品1上映| 好久久免费视频高清| 伊人久久大香线蕉无码麻豆| 精品久久久无码人妻中文字幕豆芽| 99久久精品免费| 久久久久AV综合网成人| 亚洲国产成人久久一区久久| 国内精品久久久人妻中文字幕| 久久久久亚洲精品男人的天堂| 久久超碰97人人做人人爱| 一级a性色生活片久久无少妇一级婬片免费放|