類模板(泛型編程)

什麼是類模板

類似函數模板,淡化數據類型,使用通用數據類型的模板。對僅成員數據類型不同的類的抽象,比如,有兩個或多個類,其功能是相同的,僅僅是數據類型的不同,那就可以聲明爲類模板。

一般形式:template  <typename 參數名1,typename  參數名2,...>

template<typename T>
class Test
{
    Test(T t){}
    T Get() {}
    void Set(T val) {}
private: 
    T DateMember;//類屬(類型參數化)參數必須至少在類說明中出現一次
};

int main()
{
    Test<int> a(10);//類模板一定要顯示調用
    a.Set(20);
    a.Get();
    system("pause");
    return 0;
}
  • 類模板用於實現類所需數據的類型參數化
  • 類模板在表示如數組、表、圖等數據結構顯得特別重要,這些數據結構的表示和算法不受所包含的元素類型的影響
  • 和函數模板一樣都需要進行二次編譯(在聲明的地方對模板代碼本身進行編譯,在調用的地方對參數替換後在進行編譯)
  • 函數模板可以自動類型推導,類模板不能自動類型推導

繼承中的類模板

子類從模板類繼承時,需要讓編譯器知道父類的數據類型具體是什麼。

怎麼理解上面的話:以爲在類初始化對象時需要分配內存空間大小,如果不顯示聲明,那麼這個類無法初始化(數據類型的本質:固定大小內存塊的別名)

類模板派生普通類

template<typename T>
class A
{
public:
    A(T x)
    {
        t = x;
    }
    void Print()
    {
        cout << "t = " << t << endl;
    }
protected:
    T t;
};

class B:public A<int>
{
public:
    B(int a, double b) :A<int>(a)//必須顯示聲明
    {
        y = b;
    }
    void Print()
    {
        A<int>::Print();//必須顯示聲明
        cout << "y = " << y << endl;
    }
private:
    double y;
};

int main()
{
    A<int> a(3);//必須顯示聲明
    a.Print();

    B b(8, 2.5);
    b.Print();
    system("pause");
    return 0;
}

在定義B類時,A類已實例化成了int型的模板類(編譯時完成)。

類模板派生類模板

template<typename T>
class A
{
public:
    A(T x)
    {
        t = x;
    }
    void Print()
    {
        cout << "t = " << t << endl;
    }
protected:
    T t;
};

template<typename T>
class B:public A<T>
{
public:
    B(int a, double b) :A<T>(a)//必須顯示聲明
    {
        y = b;
    }
    void Print()
    {
        A<T>::Print();//必須顯示聲明
        cout << "y = " << y << endl;
    }
private:
    T y;
};

int main()
{
    A<int> a(3);//必須顯示聲明
    a.Print();

    B<T> b(8, 2.5);
    b.Print();
    system("pause");
    return 0;
}

類模板的作用

是泛型編程的基礎,就是用獨立於任何特定類型的方式來編寫代碼,簡單的來說,類是對象的抽象,對象時具體的,而模板是類的抽象,用模板能定義出具體的類。

C++中多態分爲兩種:

動態:虛函數

靜態:函數重載,泛型編程

類模板中的static關鍵字

  • 從類模板實例化的每個模板類有自己的類模板數據成員,該模板類的所有對象共享一個static數據成員
  • 和非模板類的static數據成員一樣,模板類的static數據成員也應該在文件範圍定義和初始化
  • 每個模板類有自己的類模板的static數據成員副本
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
 
template <typename T>
class A
{
public:
    static T m_a;
};
 
template <typename T>
T A<T>::m_a = 0;
 
int main()
{
    A<int> a1, a2, a3;
    a1.m_a = 10;
    a2.m_a++;
    a3.m_a++;
    cout << A<int>::m_a << endl;
 
    A<char> a4, a5, a6;
    a4.m_a = 'a';
    a5.m_a++;
    a6.m_a++;
    cout << A<char>::m_a << endl;
 
    system("pause");
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章