• <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(成員函數模板)

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

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

            為了更好的說明問題,我們自己定義一個Smart Pointer(智能指針,這里只是示例,所以定義是不完整和不完善的),假設現在我們手上有這樣三個類:MusicProduct、CD、MP3,類之間的關系圖如下:
            類圖
            我們定義的智能指針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;
            };

            現在有一個播放函數:

            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();
            	}
            }

            如果有下面這樣的調用,會不會有什么問題呢?

            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;
            }

            實際編譯時會發生錯誤,在Visual Studio 2008下面提示如下錯誤:

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

            提示“SmartPtr”不能轉換為“const SmartPtr &” 。因為在編譯器眼里SmartPtr和SmartPtr是兩個完全不相關的東西,他們之間沒有繼承關系。我們可以寫一個隱式類型轉換,但實際操作起來不太理想,正如前面所說,STL的auto_ptr采用了Member Function Templates(成員函數模板)技術。我們可以再SmartPtr的定義中增加成員函數模板實現代碼,具體如下:

            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;
            };

            之后就可以正常編譯和運行了??雌饋砗苌衿姘?,看看《More Effective C++》對此的解釋:
            現在請你注意,這可不是魔術——不過也很接近于魔術。假設編譯器有一個指向 T 對象的智能指針,它要把這個對象轉換成指向“T 的基類”的智能指針。編譯器首先檢查 SmartPtr的類定義,看其有沒有聲明明確的類型轉換符,但是它沒有聲明。編譯器然后檢查是否存在一個成員函數模板,并可以被實例化成它所期望的類型轉換。它發現了一個這樣的模板(帶有形式類型參數 newType) ,所以它把newType綁定成 T 的基類類型來實例化模板。 這時,惟一的問題是實例化的成員函數代碼能否被編譯:傳遞指針 pointee 到指向“T 的基類”的智能指針的構造函數,必須合法的。指針pointee 是指向 T 類型的,把它轉變成指向其基類(public 或 protected)對象的指針必然是合法的,因此類型轉換操作符能夠被編譯,可以成功地把指向 T 的智能指針隱式地類型轉換為指向“T 的基類”的智能指針。

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

            --------------------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
            執行 cl.exe 時出錯.
             
            MftDemo.exe - 1 error(s), 0 warning(s)

            2. MS關于Member Function Templates的更多一些介紹

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

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

            原創文章,轉載請注明:
            本文出自程序人生 >> Member Function Templates(成員函數模板)
            作者:代碼瘋子

            posted on 2011-09-28 18:27 LoveBeyond 閱讀(2128) 評論(0)  編輯 收藏 引用 所屬分類: 雜亂無章

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

            導航

            統計

            留言簿(1)

            文章分類

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            友情鏈接:C++博客 LoveBeyond 代碼瘋子 程序人生 C++技術博客
            日韩AV毛片精品久久久| 亚洲va中文字幕无码久久不卡 | 久久精品国产第一区二区三区| 久久亚洲精品无码播放| 免费无码国产欧美久久18| 久久精品a亚洲国产v高清不卡| 热久久这里只有精品| 久久人做人爽一区二区三区| 狠狠色丁香久久婷婷综合五月| 亚洲午夜精品久久久久久人妖| 日韩欧美亚洲综合久久影院Ds| 久久亚洲精品无码AV红樱桃| 99久久精品国产毛片| 成人午夜精品无码区久久 | 香蕉久久夜色精品国产尤物| 久久精品国产亚洲AV麻豆网站| 久久精品一区二区三区中文字幕| 亚洲精品国产美女久久久| 久久国产精品波多野结衣AV | 久久久久久国产精品无码下载| 久久综合香蕉国产蜜臀AV| 久久精品国产一区二区电影| 久久国产精品成人片免费| 久久亚洲中文字幕精品一区| 国产精品成人久久久久三级午夜电影 | 香蕉aa三级久久毛片| 久久久久国产精品| 久久久久亚洲AV无码麻豆| 欧美日韩精品久久久免费观看| 精品水蜜桃久久久久久久| AV色综合久久天堂AV色综合在| 国产激情久久久久久熟女老人| 欧美色综合久久久久久| 久久久艹| 久久久久久综合网天天| 精品久久久中文字幕人妻| 欧美精品九九99久久在观看| 久久乐国产综合亚洲精品| 久久亚洲精品无码aⅴ大香 | 人人狠狠综合久久亚洲婷婷| 99久久精品国内|