• <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ù)博客
            91麻豆国产精品91久久久| 伊人久久综合无码成人网| 久久精品成人| 97久久婷婷五月综合色d啪蜜芽| 无码人妻少妇久久中文字幕蜜桃| 国产一区二区三区久久精品| 久久精品?ⅴ无码中文字幕| 亚洲第一极品精品无码久久| 国产精品成人99久久久久| 久久久久久综合网天天| 国产亚洲精午夜久久久久久| 亚洲综合伊人久久大杳蕉| 久久精品无码一区二区日韩AV| 无码伊人66久久大杳蕉网站谷歌 | 丁香五月综合久久激情| 久久精品免费一区二区| 久久国产精品免费| 99久久久国产精品免费无卡顿| 久久99国产精品久久99小说| 久久精品成人免费国产片小草| 99久久国产综合精品麻豆| 久久综合亚洲鲁鲁五月天| 国产精品嫩草影院久久| 99久久99这里只有免费费精品| 久久久精品国产免大香伊 | 久久久精品久久久久久| 狠狠狠色丁香婷婷综合久久俺| 国产成年无码久久久免费| 久久经典免费视频| 人人狠狠综合久久亚洲高清| 94久久国产乱子伦精品免费| 国产精品99久久久久久人| 精品久久久噜噜噜久久久| 久久亚洲中文字幕精品有坂深雪| 久久亚洲AV无码精品色午夜| 亚洲欧美一级久久精品| 婷婷久久综合九色综合绿巨人| 欧美精品一区二区久久| 四虎影视久久久免费| 武侠古典久久婷婷狼人伊人| 亚洲国产精品成人久久蜜臀|