當前位置 主頁 > 網站技術 > 代碼類 > 最大化 縮小

    C++ 泛型編程詳解(2)

    欄目:代碼類 時間:2020-02-06 21:08

    // 函數模板
    template<typename T> 
    void tfunc(const T& t) {
     cout << "template: " << t << endl;
    }
    
    // 函數模板實例化,不用寫函數的實現,編譯器會生成該類型的模板具體化函數
    template void tfunc<char>(const char& c);
    

    類模板

    類模板可以指定默認模板參數(函數模板不可以),跟函數參數的默認值一樣,必須從右向左連續賦值默認類型,如果實例化對象時又傳遞了類型,默認類型會被覆蓋掉,跟函數參數是一樣的
    創建對象時需要傳遞模板參數列表,模板參數列表加在類名后面 ClassName< typename T > classN; 如果類的模板參數列

    表有默認值,可以不傳模板參數,但一定要加 <> 如 ClassName< > classN; 創建堆區對象的時候,所有的類名稱后面都要加模板參數列表,如 ClassName< typename T >* classN = new ClassName< typename T>; 除了類內,其他地方出現 ClassName 的地方一般都要加模板參數列表

    template<typename T = int, typename Y = char> // 此處指定了模板默認參數,部分指定必須從右到左指定
    class Test {
    public:
     Test(T t, Y y) : t(t), y(y) {
     }
     void tfunc();
    private:
     T t;
     Y y;
    };
    template<typename T, typename Y> // 類模板的函數在類外實現,需要加上模板參數列表,但不需要加指定的默認模板參數
    void Test<T, Y>::tfunc() { // 類外使用Test需要加模板參數
     cout << t << " " << y << endl;
    }
    int n = 2;
    double d = 2.1;
    Test<int, double> test(n, d); // 此處如果使用默認模板參數可定義為 Test<> test(int(2), char('a'));
    test.tfunc();
    // 運行結果:2 2.1

    類模板的繼承,類模板被繼承后參數的傳遞方式主要有兩種,一種是直接在子類繼承父類的時候,為父類指定固定的類型,二是通過子類模板參數列表傳遞

    // ====== 測試一 ======
    template<typename T, typename Y>
    class A {
    public:
     A(T t, Y y) {
     }
    };
    class Test : public A<int, double> { // 父類是類模板,子類是普通類
    public:
     Test() : A<int, double>(2, 2.1) {
     }
    };
    Test();
    // ====== 測試二 ======
    template<typename T, typename Y>
    class A {
    public:
     A(T t) {
     }
    };
    template<typename X, typename Z, typename P>
    class Test : public A<X, P> {
    public:
     Test(X x, Z z, P p) : A<X, P>(x) {
     }
    };
    Test<int, double, char>(int(2), double(2.1), char('a'));

    類模板的多態,在創建對象時,分為子類沒有模板(CFather<short, char>*cf = new CSon;)和子類有模板(CFather<short, char> *cf = new CSon<short, int, char>)兩種,子類和父類的模板參數列表可以不一樣,但一定要對應好

    // ====== 測試一 ======
    template<typename T, typename Y> 
    class A {
    public:
     virtual void tfunc(T t, Y y) = 0;
    };
    class Test : public A<int, double> { 
    public:
     virtual void tfunc(int n, double d) {
     cout << n << " " << d << endl;
     }
    };
    // 父類是類模板,子類是普通類,在多態情況下父類需要指定模板參數,子類就不用了
    A<int, double>* a = new Test;
    a->tfunc(2, 2.1);
    // 運行結果:2 2.1
    // ====== 測試二 ======
    template<typename T, typename Y> 
    class A {
    public:
     virtual void tfunc(T t, Y y) = 0;
    };
    template<typename X, typename Z, typename P>
    class Test : public A<X, P> {
    public:
     virtual void tfunc(X x, P p) {
     cout << x << " " << p << endl;
     }
    };
    
    // 父類是類模板,子類是類模板,在多態情況下父類和子類都需要指定模板參數
    A<int, double>* a = new Test<int, char, double>;
    a->tfunc(2, 2.1);
    // 運行結果:2 2.1
    
    下一篇:沒有了
777亚洲人成视频免费视频