乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      (C 模板類)

       閑來看看 2013-02-28

      和函數(shù)一樣,C++中的class也可以類型參數(shù)化,其中容器類是極具這一特征的。對于模板類的基本定義和使用,可以參考STL,這里就不做過多的贅述了。下面將主要介紹一下與其相關的高級實用特征。

      一、模板的特化:

          這里可以先將類模板特化與面向對象中的多態(tài)進行一個簡單的比較,這樣可以便于我們對它的理解,也同樣有助于指導我們在實際的開發(fā)中應用這一C++技巧。眾所周知,對于多態(tài)而言,提供的是統(tǒng)一的接口和不同的實現(xiàn)類實例,其最終的行為將取決于實現(xiàn)類中的實現(xiàn),相信每一個有面向對象基礎的開發(fā)者對于這一概念并不陌生。而模板特化則要求必須提供一個標準的模板類(等同于多態(tài)中的接口),與此同時再為不同的類型提供不同的特化版本。在模板特化類中,我們首先需要保證類名是相同的,只是模板參數(shù)不再使用抽象的類型,而是直接使用具體的類型來實例化該模板類。在調用時,編譯器會根據(jù)調用時的類型參數(shù)自動選擇最為合適的模板類,即如果有特化模板類中的類型參數(shù)和當前調用類型相匹配的話,則首選該特化模板類,否則選擇最初的標準模板類。見如下用例(請注意代碼中的說明性注釋)

        1     #include <stdio.h>
        2     #include <string.h>
        3     
        4     //1. 這里我們先聲明了一個通用類型的模板類。這里要有類型參數(shù)必須包含hashCode()方法。
        5     //否則,該類型在編譯期實例化時將會導致編譯失敗。
        6     template <typename T>
        7     class CalcHashClass { //該類為標準模板類(等同于多態(tài)中的接口)
        8     public:
        9         CalcHashClass(T const& v) : _value(v) {
       10         }
       11         int hashCode() {
       12             printf("This is 'template <typename T> class CalcHashClass'.\n");
       13             return _value.hashCode() + 10000;
       14         }
       15     private:
       16         T _value;
       17     };
       18     
       19     //2. int類型實例化特化模板類。
       20     template <>
       21     class CalcHashClass<int> {
       22     public:
       23         CalcHashClass(int const& v) : _value(v) {
       24         }
       25         int hashCode() {
       26             printf("This is 'template <> class CalcHashClass<int>'.\n");
       27             return _value * 101;
       28         }
       29     private:
       30         int _value;
       31     };
       32     
       33     //3. const char*類型實例化的特化模板類
       34     template<>
       35     class CalcHashClass<const char*> {
       36     public:
       37         CalcHashClass(const char* v) {
       38             _v = new char[strlen(v) + 1];
       39             strcpy(_v,v);
       40         }
       41         ~CalcHashClass() {
       42             delete [] _v;
       43         }
       44         int hashCode() {
       45             printf("This is 'template <> class CalcHashClass<const char*>'.\n");
       46             int len = strlen(_v);
       47             int code = 0;
       48             for (int i = 0; i < len; ++i)
       49                 code += (int)_v[i];
       50             return code;
       51         }
       52     
       53     private:
       54         char* _v;
       55     };
       56     
       57     //4. 輔助函數(shù),用于幫助調用者通過函數(shù)的參數(shù)類型自動進行類型推演,以讓編譯器決定該
       58     //實例化哪個模板類。這樣就可以使調用者不必在顯示指定模板類的類型了。這一點和多態(tài)有
       59     //點兒類似。
       60     template<typename T>
       61     inline int CalcHashCode(T v) {
       62         CalcHashClass<T> t(v);
       63         return t.hashCode();
       64     }
       65     
       66     //5. 給出一個范例類,該類必須包含hashCode方法,否則將造成編譯錯誤。
       67     class TestClass {
       68     public:
       69         TestClass(const char* v) {
       70             _v = new char[strlen(v) + 1];
       71             strcpy(_v,v);
       72         }
       73         ~TestClass() {
       74             delete [] _v;
       75         }
       76     public:
       77         int hashCode() {
       78             int len = strlen(_v);
       79             int code = 0;
       80             for (int i = 0; i < len; ++i)
       81                 code += (int)_v[i];
       82             return code;
       83         }
       84     private:
       85         char* _v;
       86     };
       87     
       88     int main() {
       89         TestClass tc("Hello");
       90         CalcHashClass<TestClass> t1(tc);
       91         printf("The hashcode is %d.\n",t1.hashCode());
       92         //這里由于為模板類TestClass提供了基于int類型的模板特化類,因此編譯器會自動選擇
       93         //更為特化的模板類作為t2的目標類。
       94         CalcHashClass<int> t2(10);
       95         printf("The hashcode is %d.\n",t2.hashCode());
       96     
       97         //在上面的示例中,我們通過顯示的給出類型信息以實例化不同的模板類,這是因為模板類
       98         //的類型信息是無法像模板函數(shù)那樣可以通過函數(shù)參數(shù)進行推演的,為了彌補這一缺失,我們可以
       99         //通過一個額外的模板函數(shù)來幫助我們完成這一功能。事實上,這一技巧在Thinking in Java中
      100         //也同樣給出了。
      101         printf("Ths hashcode is %d.\n",CalcHashCode(10));
      102         printf("Ths hashcode is %d.\n",CalcHashCode("Hello"));
      103         return 0;
      104     }
      105     //This is 'template <typename T> class CalcHashClass'.
      106     //The hashcode is 10500.
      107     //This is 'template <> class CalcHashClass<int>'.
      108     //The hashcode is 1010.
      109     //This is 'template <> class CalcHashClass<int>'.
      110     //Ths hashcode is 1010.
      111     //This is 'template <> class CalcHashClass<const char*>'.
      112     //Ths hashcode is 500.

          通過上面的示例可以看出,模板特化是依賴于編譯器在編譯期動態(tài)決定該使用哪個特化類,或是標準模板類的。相比于多態(tài)的后期動態(tài)綁定,該方式的運行效率更高,同時靈活性也沒有被更多的犧牲。
          下面將給出一個結合模板特化和多態(tài)的示例(請注意代碼中的說明性注釋)

       
       1     #include <stdio.h>
       2     #include <string.h>
       3     
       4     //1. 定義一個接口
       5     class BaseInterface {
       6     public:
       7         virtual ~BaseInterface() {}
       8         virtual void doPrint() = 0;
       9     };
      10     
      11     //2. 標準模板類繼承該接口,同時給出自己的doPrint()實現(xiàn)。
      12     template<typename T>
      13     class DeriveClass : public BaseInterface {
      14     public:    
      15         void doPrint() {
      16             printf("This is 'template<typename T> class DeriveClass'.\n");
      17         }
      18     };
      19     
      20     //3. 基于int類型特化后的DeriveClass模板類,同樣繼承了該接口,也給出了自己的DoPrint()實現(xiàn)。
      21     template<>
      22     class DeriveClass<int> : public BaseInterface {
      23     public:    
      24         void doPrint() {
      25             printf("This is 'template<> class DeriveClass<int>'.\n");
      26         }
      27     };
      28     
      29     //4. 對象創(chuàng)建輔助函數(shù),該函數(shù)可以通過參數(shù)類型的不同,實例化不同的接口子類。
      30     template<typename T>
      31     inline BaseInterface* DoTest(T t) {
      32         return new DeriveClass<T>;
      33     }
      34     
      35     int main() {
      36         BaseInterface* b1 = DoTest(4.5f);
      37         b1->doPrint();
      38         BaseInterface* b2 = DoTest(5);
      39         b2->doPrint();
      40         delete b1;
      41         delete b2;
      42         return 0;
      43     }
      44     //This is 'template<typename T> class DeriveClass'.
      45     //This is 'template<> class DeriveClass<int>'.    

         
      二、模板部分特化:

          有的書中將其翻譯成模板偏特化,或者是模板的局部特化,但含義都是相同的。為了便于理解,我們可以將上面的模板特化稱為模板全部特化,即模板類的類型參數(shù)全部被特化了。顧名思義,模板部分特化只是將其中一部分類型參數(shù)進行了特化聲明,因此也可以將模板特化視為模板部分特化的一種特殊形式。由于應用場景基本相同,因此下面的代碼將僅僅給出最基本的示例和注釋說明,以幫助大家熟悉他的語法即可:

       
       1     //1. 標準模板類。
       2     template<typename T1, typename T2>
       3     class MyClass {
       4         ... ...
       5     };
       6     //2. 兩個模板參數(shù)具有相同類型的部分特化類。
       7     template<typename T>
       8     class MyClass<T,T> {
       9         ... ...
      10     }
      11     //3. 第二個類型參數(shù)是int
      12     template<typename T>
      13     class MyClass<T,int> {
      14         ... ...
      15     }
      16     //4. 兩個模板參數(shù)都是指針。
      17     template<typename T1,typename T2>
      18     class MyClass<T1*,T2*> {
      19         ... ...
      20     }
      21     //5. 兩個模板參數(shù)都是相同類型的指針。
      22     template<typename T>
      23     class MyClass<T*,T*> {
      24         ... ...
      25     }
      26     //6. 調用示例代碼。
      27     int main() {
      28         MyClass<int,float> c1;         //調用MyClass<T1,T2>
      29         MyClass<float,float> c2;    //調用MyClass<T,T>
      30         MyClass<float,int> c3;      //調用MyClass<T,int>
      31         MyClass<int*,float*> c4;    //調用MyClass<T1*,T2*> 
      32         MyClass<int*,int*> c5;      //調用MyClass<T*,T*>
      33         return 0;
      34     }
       

         
      三、缺省模板實參:

          和函數(shù)的缺省參數(shù)一樣,C++的模板也同樣支持缺省類型參數(shù)。

       
       1     //1. 第二個類型參數(shù)的缺省值是vector<T>
       2     template<typename T, typename T2 = std::vector<T> >
       3     class MyClass {
       4         ... ... 
       5     }
       6     int main() {
       7         MyClass<int> c1;            //第二個類型參數(shù)是vector<int> 
       8         MyClass<int,list<int> > c2; //第二個類型參數(shù)是list<int> 
       9         return 0;
      10     }
       

          這種使用缺省模板參數(shù)的代碼,在STL中比比皆是。
          
      四、非類型模板參數(shù):

          模板的類型參數(shù)不僅僅可以是類型,也可以是常量,但是常量本身的類型是有限制的,不是所有類型的常量都可以,目前只是整型常量和外部鏈接對象的指針可以,而浮點型等其他原始類型,或自定義類型均不可。

       
       1     template<typename T, int MAXSIZE>
       2     class MyContainer {
       3     public:
       4         int capacity() const { return MAXSIZE; }
       5         ... ...
       6     private:
       7         T elements[MAXSIZE];
       8     };
       9      
      10     int main() {
      11         MyContainer<int,50> c1;
      12         return 0;
      13     }
      14     和普通類型模板一樣,非類型模板參數(shù)也可以有缺省值,如:
      15     template<typename T, int MAXSIZE = 10>
      16     class MyContainer {
      17     public:
      18         int capacity() const { return MAXSIZE; }
      19         ... ...
      20     private:
      21         T elements[MAXSIZE];
      22     };

         
          最后需要說明的是,不管是普通模板類還是非類型模板類,只要其類型不同,或是常量值不同,就不能將其視為相同類型的對象,這一點同樣適用于模板函數(shù)。

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多