• <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水果派| 国产99久久精品一区二区| 99久久精品国产毛片| 久久精品国产亚洲av水果派| 久久国产精品-久久精品| 国产精品美女久久福利网站| 久久―日本道色综合久久| 国产成人久久久精品二区三区| 浪潮AV色综合久久天堂| 国内精品免费久久影院| 免费无码国产欧美久久18| 国产一久久香蕉国产线看观看 | 久久久一本精品99久久精品66| 欧美精品一本久久男人的天堂| 欧美精品丝袜久久久中文字幕 | 久久久久久亚洲AV无码专区| 久久久青草久久久青草| 久久久久久久久波多野高潮| 久久香蕉国产线看观看99| 国产精品久久婷婷六月丁香| 国内精品久久久久| 久久精品青青草原伊人| 久久国产免费| 国产精自产拍久久久久久蜜| 久久精品aⅴ无码中文字字幕不卡| 国产午夜精品理论片久久影视| 综合久久精品色| 一本色道久久88综合日韩精品 | 99久久精品国产麻豆| 久久成人国产精品免费软件| 久久乐国产精品亚洲综合| 国产一区二区三区久久精品| 久久人人爽人人爽人人片av高请 | 超级碰久久免费公开视频| 精品国产91久久久久久久|