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

            woaidongmao

            文章均收錄自他人博客,但不喜標題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            c++模板基礎(chǔ)

            只有使用C++語言的少數(shù)用戶才努力嘗試去理解模板的基本原理。然而那些希望去探索更多高級用法的人往往發(fā)現(xiàn)自己需要努力去理解模板是如何被語言所支持的,因為缺乏明確的說明。一個很大的問題在于一些工具只實現(xiàn)了C++標準的一個子集。本文將指出它們共同的缺陷并深入剖析如何使用C++模板快速產(chǎn)生可重用和高效的代碼。

            模板功能應用的典型是通過一系列模板類形成的完整類庫,特別是STL和ATL。標準C++庫(STL)提供了很多可重用和靈活的類及算法,而ATL則是使用C++進行COM編程的事實標準。要掌握這些及其它的模板庫,理解模板是如何工作的這一基礎(chǔ)是非常重要的。

            函數(shù)模板

            int main()
            {
                0 cout<<add(2,3)<<endl;
                1 cout<<add(2.1,3)<<endl;
                2 cout<<add(2,3.2)<<endl;
                3 cout<<add(2.2,3.3)<<endl;
                4 cout<<add("hello eone ","world")<<endl;
                return 0;
            }

                 也可以通過宏定義#define add(a,b) ((a)+(b))來實現(xiàn),但是指針(字符串)不能直接相加.對于2,3,4需要進行模板特化.

            通過重載函數(shù),我們能夠完成多種不同數(shù)據(jù)類型的相同操作。要實現(xiàn)兩個double數(shù)值的加法和兩個整數(shù)類型的加法,我們可以使用一個重載函數(shù):

            int add(const int x, const int y)

            {

            return x + y;

            }

            double add(const double x, const double y)

            {

            return x + y;

            }

            這時,編譯器將根據(jù)它們的參數(shù)正確地解決這一問題。

            // 調(diào)用int add(const int, const int);

            const int z1 = add(3, 2);

            // 調(diào)用double add(const double, const double);

            const double z2 = add(3.0, 2.0);

            如果我們需要處理其它類型,我們就不得不提供其他函數(shù)重載。對每個不同的數(shù)據(jù)類型實現(xiàn)一個函數(shù)重載,它們都遵循相同的模式,每當我們需要調(diào)用針對某一數(shù)據(jù)類型的函數(shù)時,原則上編譯器為我們生成相應的代碼。而一個模板函數(shù)則以如下方式實現(xiàn):

            template<class T>

            const T add(const T &t1, const T &t2)

            {

            return t1 + t2;

            }

            從概念上來說,編譯器通過模板關(guān)鍵字(后面跟隨著模板由一或多個模板參數(shù)構(gòu)成的參數(shù)列表)來識別模板。當為某一具體類型調(diào)用add時,編譯器將根據(jù)模板定義并用給定的類型替換出現(xiàn)在模板中的參數(shù)。在這個例子中,模板參數(shù)列表由一個獨立的類型模板參數(shù)T構(gòu)成。使用一個模板函數(shù)替代函數(shù)重載,編譯器可以自動為所需的新類型生成代碼

            我們可以對任何擁有+操作符定義的類型使用add模板。假設(shè)一個自定義的String類提供了字符串連接并知道如何將自身寫入到std::ostream。因為String與該模板函數(shù)兼容,因此我們可以調(diào)用它來實現(xiàn)字符串相加:

            // 示例字符串

            const string strBook("book");

            const string strWorm("worm");

            // 顯示 "bookworm".

            cout << add(strBook, strWorm) << endl;

            Seeing that we intended to add two String values, the compiler will generate the appropriate add function on our behalf, which would look something like:

            const String add(const String &t1, const String &t2)

            {

            return t1 + t2;

            }

            顯式實例化

            調(diào)用模板函數(shù)時,編譯器將先把正確的類型實例化模板。雖然標準允許顯式模板實例化,然而并非所有廠商都能夠正確地實例它。例如,Visual C++ 6.0 會潛在地調(diào)用錯誤的函數(shù)::

            template<class T>

            int getSize(void) {

            return sizeof(T);

            }

            // 輸出4,應該為8

            cout << "double: " << getSize<double>() << endl;

            // 輸出4,正確

            cout << "int: " << getSize<int>() << endl;

            跨平臺代碼設(shè)計者不希望依賴于顯式模板函數(shù)實例化,除非有更好的編譯器能夠?qū)λ峁┯行У闹С?

             

             

            類似于函數(shù)模板,模板也可以應用于類。模板可以用于根據(jù)普通模式提供一系列類。如果我們需要一套完整的算術(shù)運算來補充add函數(shù),我們可以考慮使用一個類。通過模板,它就可以根據(jù)類型參數(shù)化為一個普通類:

            template<class T>

            class CCalculator

            {

            public:

            CCalculator(const T &x, const T &y) : m_x(x), m_y(y){ }

            ~CCalculator(void){ }

            const T add(void){ return m_x + m_y; }

            const T sub(void){ return m_x - m_y; }

            const T mult(void){ return m_x * m_y; }

            const T div(void){ return m_x / m_y; }

            private:

            const T m_x;

            const T m_y;

            };

            要實例化模板類,我們需要提供一個指定類型:

            // 創(chuàng)建一個整數(shù)計算對象

            CCalculator<int> calc(5, 2);

            // 結(jié)果應該為 10

            const int z = calc.mult();

            如函數(shù)模板一樣,編譯器為模板不同類型的引用創(chuàng)建不同的類。這為代碼重用提供了一個強大的機制,允許單個模板用于任何兼容的數(shù)據(jù)類型

            模板編輯模型

            在編寫模板類時,函數(shù)定義通常與它們的聲明一起保存在頭文件中,而不使用另外的.cpp文件。否則可能會導致鏈接錯誤。這是因為大多數(shù)編譯器要求模板定義在以頭文件為單位的轉(zhuǎn)譯單元中有效

            這個行為的原因是模板只是一個模式,同樣它們不直接產(chǎn)生代碼(直到編譯器遇到一個應用實例)。如果我們創(chuàng)建一個CCalculator<int> 實例并調(diào)用其中的某個類方法,編譯器將需要找到函數(shù)定義。如果頭文件中包含了該定義則一切都會是正確的。但是如果定義存在于.cpp文件中,編譯器不能期望在此時找到匹配的模式并利用其產(chǎn)生所需的代碼。然而,C++標準提供了一個機制對編譯器進行輔助。Export關(guān)鍵字可以使通知編譯器我們提供了一個分離的編輯模板:

            // MyTemplateFunction.h

            template<class T>

            void myTemplateFunction(const T &t1);

            // MyTemplateFunction.cpp

            export template <class T>

            void myTemplateFunction(const T &t1)

            {

            ...

            }

            現(xiàn)在,大多數(shù)編譯器要求模板定義通過頭文件包含被顯式添加到轉(zhuǎn)譯單元,雖然標準期望能夠獨立定義于.cpp文件中。這兩個不同的模板編輯模型即為包含模型和分離模型。在編寫時,我所知的支持分離模型的唯一的編譯器是Comeau C++。Comeau 的使用了不少方法來實現(xiàn)對標準中所定義的export關(guān)鍵字用法,但目前也還只是beta版本而已

            typename關(guān)鍵字

            另一個與模板相關(guān)的關(guān)鍵字是typename關(guān)鍵字,它有兩種用法。參數(shù)下面的模板類:

            template<class T>

            void myFunction(void)

            {

            // 這里可能會有問題

            T::x1 * x2;

            }

            初次講到的時候可能會以為myFunction聲明了一個T::x1類型的指針變量x2。然而,這個函數(shù)也能夠表示類T的成員變量x1與全局變量x2的二進制乘法操作。使用typename關(guān)鍵字可以告訴編譯器某個未知標識符是一個類型:

            // T:x1 是一個類型,而x2是一個指針

            typename T:x1* x2;

            第二種用法是在指定模板參數(shù)時替換class關(guān)鍵字:

            // 下面的兩種方法是等效的...

            template<class T1, class T2>;

            template<typename T1, typename T2>;

            標準允許以上任意一種方法,它們都是合法的。

            成員函數(shù)模板

            除了全局模板函數(shù)外,語言也支持成員模板函數(shù):一個類可以擁有帶有模板參數(shù)列表的成員函數(shù)。參考下面的非模板類,它的構(gòu)造函數(shù)被模板化:

            class CTypeSize

            {

            public:

            template<class T>

            CTypeSize(const T &t1) :

            m_nSize(sizeof(t1))

            {

            }

            ~CTypeSize(void){ };

            int getSize(void) const{ return m_nSize; }

            private:

            const int m_nSize;

            };

            當模板成員函數(shù)被調(diào)用時,編譯器使用模板模式為給定類型生成代碼。這種情況下,我們能夠使用任意類型變量創(chuàng)建一個CtypeSize實例:

            // 顯示12

            CTypeSize t1("Hello World");

            cout << t1.getSize() << endl;

            // 在VC++6/Win32中顯示8

            CTypeSize t2(7.0);

            cout << t2.getSize() << endl;

            某些時候,成員模板是實現(xiàn)拷貝構(gòu)造函數(shù)最有效的方法,參考一個只有一個交易會的簡單容器類:

            template<class T>

            class CSingle

            {

            public:

            CSingle(const T &t1) : m_Value(t1) { }

            ~CSingle(void){ }

            T m_Value;

            };

            它導致下面的問題:

            // 創(chuàng)建一個整數(shù)容器

            CSingle<int> x(7);

            // 這里需要一個拷貝構(gòu)造...

            CSingle<double> y(x);

            通過使用成員模板,拷貝構(gòu)造就能夠輕松完成:

            template<class S>

            CSingle(const CSingle<S> &s1) : m_Value(s1.m_Value) { }

            當編輯器能夠?qū)㈩愋蚑的實例轉(zhuǎn)換為類型S時,這是可行的;這是因為double可以從一個整數(shù)構(gòu)造。

            總結(jié)

            模板是C++的一個強大特征,它允許從數(shù)據(jù)類型中抽象出算法。本文介紹了模板定義和實例化的基礎(chǔ),包括函數(shù)、類及成員模板的區(qū)別。

            posted on 2008-09-01 12:10 肥仔 閱讀(665) 評論(0)  編輯 收藏 引用 所屬分類: C++ 模板

            亚洲午夜无码AV毛片久久| 国产激情久久久久久熟女老人| 久久久久亚洲精品男人的天堂| 99麻豆久久久国产精品免费| 亚洲成色WWW久久网站| 亚洲精品视频久久久| 亚洲欧美另类日本久久国产真实乱对白 | 久久无码AV中文出轨人妻| 国产精品久久久久久久| 91精品国产综合久久婷婷| 精品久久久久久久久午夜福利| 亚洲AV日韩精品久久久久| 人妻精品久久久久中文字幕一冢本 | 久久久女人与动物群交毛片| 久久精品国产久精国产果冻传媒| 亚洲精品97久久中文字幕无码| 日本国产精品久久| 久久精品国产亚洲av麻豆蜜芽| 亚洲国产另类久久久精品| 久久天天躁狠狠躁夜夜avapp | 中文字幕无码久久久| 亚洲中文字幕无码久久精品1 | 色综合久久久久综合体桃花网| 亚洲AV无码久久精品狠狠爱浪潮 | 久久久久人妻一区二区三区vr | 久久精品国产亚洲精品2020| 99久久人妻无码精品系列| 青青青国产精品国产精品久久久久| 久久香蕉国产线看观看99| 久久激情五月丁香伊人| 人妻无码中文久久久久专区| AAA级久久久精品无码片| 免费精品久久久久久中文字幕| 久久久久久久久66精品片| 久久久久久亚洲Av无码精品专口 | 国产精品久久久99| 2021国产精品久久精品| 91超碰碰碰碰久久久久久综合| 久久国产精品国语对白| 久久久久亚洲AV片无码下载蜜桃| 激情综合色综合久久综合|