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

            LoveBeyond

            Member Function Templates(成員函數(shù)模板)

            (本文最初發(fā)表于程序人生 >> Member Function Templates(成員函數(shù)模板) 作者:代碼瘋子

            Member Function Templates翻譯成中文就是成員函數(shù)模板,這個(gè)東西我個(gè)人見(jiàn)得少,最初是在STL的auto_ptr源代碼里面看到的,當(dāng)時(shí)候也不是很明白;這幾天又翻了翻《More Effective C++》,正好看到上面介紹的比較詳細(xì),就找了點(diǎn)資料總結(jié)一下。

            為了更好的說(shuō)明問(wèn)題,我們自己定義一個(gè)Smart Pointer(智能指針,這里只是示例,所以定義是不完整和不完善的),假設(shè)現(xiàn)在我們手上有這樣三個(gè)類(lèi):MusicProduct、CD、MP3,類(lèi)之間的關(guān)系圖如下:
            類(lèi)圖
            我們定義的智能指針SmartPtr如下:

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            
            template<class T>
            class SmartPtr
            {
            public:
            	explicit SmartPtr(T* realPtr = NULL) : pointee(realPtr){}
             
            	T* operator->() const
            	{
            		return pointee;
            	}
             
            	T& operator*() const
            	{
            		return *pointee;
            	}
            private:
            	T* pointee;
            };

            現(xiàn)在有一個(gè)播放函數(shù):

            1
            2
            3
            4
            5
            6
            7
            8
            
            void displayAndPlay(const SmartPtr<MusicProduct>& pmp, int times)
            {
            	for (int i = 1; i <= times; ++i)
            	{
            		pmp->displayTitle();
            		pmp->play();
            	}
            }

            如果有下面這樣的調(diào)用,會(huì)不會(huì)有什么問(wèn)題呢?

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            
            int main(int argc, char **argv)
            {
            	CD *cd = new CD("BEYOND LIVE CD");
            	MP3 *mp3 = new MP3("BEYOND MP3");
             
            	SmartPtr<CD> cdMusic(cd);
            	SmartPtr<MP3> mp3Music(mp3);
             
            	displayAndPlay(cdMusic, 10);
            	displayAndPlay(mp3Music, 10);
             
            	return 0;
            }

            實(shí)際編譯時(shí)會(huì)發(fā)生錯(cuò)誤,在Visual Studio 2008下面提示如下錯(cuò)誤:

            1>error C2664: “displayAndPlay”: 不能將參數(shù) 1 從“SmartPtr<T>”轉(zhuǎn)換為“const SmartPtr<T> &”
            1>        with
            1>        [
            1>            T=CD
            1>        ]
            1>        and
            1>        [
            1>            T=MusicProduct
            1>        ]
            1>        ......

            提示“SmartPtr”不能轉(zhuǎn)換為“const SmartPtr &” 。因?yàn)樵诰幾g器眼里SmartPtr和SmartPtr是兩個(gè)完全不相關(guān)的東西,他們之間沒(méi)有繼承關(guān)系。我們可以寫(xiě)一個(gè)隱式類(lèi)型轉(zhuǎn)換,但實(shí)際操作起來(lái)不太理想,正如前面所說(shuō),STL的auto_ptr采用了Member Function Templates(成員函數(shù)模板)技術(shù)。我們可以再SmartPtr的定義中增加成員函數(shù)模板實(shí)現(xiàn)代碼,具體如下:

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            
            template<class T>
            class SmartPtr
            {
            public:
            	explicit SmartPtr(T* realPtr = NULL) : pointee(realPtr){}
             
            	T* operator->() const
            	{
            		return pointee;
            	}
             
            	T& operator*() const
            	{
            		return *pointee;
            	}
            	// Member Function Templates
            	template<class newType>
            	operator SmartPtr<newType>()
            	{
            		return SmartPtr<newType>(pointee);
            	}
            private:
            	T* pointee;
            };

            之后就可以正常編譯和運(yùn)行了。看起來(lái)很神奇吧,看看《More Effective C++》對(duì)此的解釋?zhuān)?br />現(xiàn)在請(qǐng)你注意,這可不是魔術(shù)——不過(guò)也很接近于魔術(shù)。假設(shè)編譯器有一個(gè)指向 T 對(duì)象的智能指針,它要把這個(gè)對(duì)象轉(zhuǎn)換成指向“T 的基類(lèi)”的智能指針。編譯器首先檢查 SmartPtr的類(lèi)定義,看其有沒(méi)有聲明明確的類(lèi)型轉(zhuǎn)換符,但是它沒(méi)有聲明。編譯器然后檢查是否存在一個(gè)成員函數(shù)模板,并可以被實(shí)例化成它所期望的類(lèi)型轉(zhuǎn)換。它發(fā)現(xiàn)了一個(gè)這樣的模板(帶有形式類(lèi)型參數(shù) newType) ,所以它把newType綁定成 T 的基類(lèi)類(lèi)型來(lái)實(shí)例化模板。 這時(shí),惟一的問(wèn)題是實(shí)例化的成員函數(shù)代碼能否被編譯:傳遞指針 pointee 到指向“T 的基類(lèi)”的智能指針的構(gòu)造函數(shù),必須合法的。指針pointee 是指向 T 類(lèi)型的,把它轉(zhuǎn)變成指向其基類(lèi)(public 或 protected)對(duì)象的指針必然是合法的,因此類(lèi)型轉(zhuǎn)換操作符能夠被編譯,可以成功地把指向 T 的智能指針隱式地類(lèi)型轉(zhuǎn)換為指向“T 的基類(lèi)”的智能指針。

            附注:
            1. Member Function Templates是C++的一個(gè)新特性,可能有些編譯器并不支持這個(gè)特性,比如VC6,編譯時(shí)似乎完全忽略了我們新加入的Member Function Templates代碼。仍然會(huì)提示如下錯(cuò)誤:

            --------------------Configuration: MftDemo - Win32 Debug--------------------
            Compiling...
            MemFunTmp.cpp
            g:\w7documents\visual studio 6.0\projects\mftdemo\memfuntmp.cpp(87) : error C2664: 'displayAndPlay' : 
                    cannot convert parameter 1 from 'class SmartPtr<class CD>' to 'const class SmartPtr<class MusicProduct> &'
                    Reason: cannot convert from 'class SmartPtr<class CD>' to 'const class SmartPtr<class MusicProduct>'
                    No constructor could take the source type, or constructor overload resolution was ambiguous
            g:\w7documents\visual studio 6.0\projects\mftdemo\memfuntmp.cpp(88) : error C2664: 'displayAndPlay' :
                    cannot convert parameter 1 from 'class SmartPtr<class MP3>' to 'const class SmartPtr<class MusicProduct> &'
                    Reason: cannot convert from 'class SmartPtr<class MP3>' to 'const class SmartPtr<class MusicProduct>'
                    No constructor could take the source type, or constructor overload resolution was ambiguous
            執(zhí)行 cl.exe 時(shí)出錯(cuò).
             
            MftDemo.exe - 1 error(s), 0 warning(s)

            2. MS關(guān)于Member Function Templates的更多一些介紹

            http://msdn.microsoft.com/en-us/library/swta9c6e.aspx

            3. 本文的完整源代碼下載
            Member Function Templates

            原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明:
            本文出自程序人生 >> Member Function Templates(成員函數(shù)模板)
            作者:代碼瘋子

            posted on 2011-09-28 18:27 LoveBeyond 閱讀(2126) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): 雜亂無(wú)章

            <2011年9月>
            28293031123
            45678910
            11121314151617
            18192021222324
            2526272829301
            2345678

            導(dǎo)航

            統(tǒng)計(jì)

            留言簿(1)

            文章分類(lèi)

            搜索

            積分與排名

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            友情鏈接:C++博客 LoveBeyond 代碼瘋子 程序人生 C++技術(shù)博客
            色综合久久无码中文字幕| 99久久综合狠狠综合久久止| 久久久久亚洲精品无码网址 | 久久婷婷五月综合97色| 久久久久亚洲精品无码蜜桃| 精品国产VA久久久久久久冰 | AV无码久久久久不卡网站下载 | 久久激情亚洲精品无码?V| 免费一级欧美大片久久网 | 欧美午夜A∨大片久久| 99久久国产亚洲综合精品| 日本久久久久亚洲中字幕 | 久久久无码人妻精品无码| 色综合合久久天天综合绕视看| 午夜精品久久久久久久无码| 无码伊人66久久大杳蕉网站谷歌| 国产精品女同一区二区久久| 精品久久久久成人码免费动漫| 久久久中文字幕| 蜜臀av性久久久久蜜臀aⅴ麻豆| 日本免费久久久久久久网站| 亚洲综合日韩久久成人AV| 久久精品无码一区二区三区免费| 亚洲va久久久噜噜噜久久狠狠 | 69久久夜色精品国产69| 久久亚洲精品国产精品婷婷 | 久久99热精品| 久久综合九色综合网站| 人人狠狠综合久久亚洲高清| 久久免费精品一区二区| 久久久久久无码Av成人影院| 久久天天躁夜夜躁狠狠| 性欧美大战久久久久久久| 国产亚洲精午夜久久久久久| 97久久国产亚洲精品超碰热| 欧美精品久久久久久久自慰| 久久99久国产麻精品66| 久久久久免费精品国产| 性高朝久久久久久久久久| 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 办公室久久精品|