C++類模板(模板類)詳解

人們需要編寫多個形式和功能都相似的函數,因此有了函數模板來減少重複勞動;人們也需要編寫多個形式和功能都相似的類,於是 C++ 引人了類模板的概念,編譯器從類模板可以自動生成多個類,避免了程序員的重複勞動。

例如,在《C++運算符重載》一章中的《C++實現可變長度的動態數組》一節中,我們實現了一個可變長的整型數組類,可能還需要可變長的 double 數組類,可變長的 CStudent 數組類,等等。如果要把類似於可變長整型數組類的代碼都重寫一遍,無疑非常麻煩。有了類模板的機制,只需要寫一個可變長的數組類模板,編譯器就會由該類模板自動生成整型、double 型等各種類型的可變長數組類了。
 

語法:

template <類型參數表>
class 類模板名{
    成員函數和成員變量
};

參數:

class類塑參數1, class類型參數2, ...

類模板中的成員函數放到類模板定義外面寫時的語法如下:

template <類型參數表>
返回值類型  類模板名<類型參數名列表>::成員函數名(參數表)
{
    ...
}

用類模板定義對象的寫法如下:

類模板名<真實類型參數表> 對象名(構造函數實際參數表);

如果類模板有無參構造函數,那麼也可以使用如下寫法:

類模板名 <真實類型參數表> 對象名;

類模板看上去很像一個類。下面以 Pair 類模板爲例來說明類模板的寫法和用法。

實踐中常常會碰到,某項數據記錄由兩部分組成,一部分是關鍵字,另一部分是值。關鍵字用來對記錄進行排序和檢索,根據關鍵字能查到值。例如,學生記錄由兩部分組成,一部分是學號,另一部分是績點。要能根據學號對學生進行排序,以便方便地檢索績點,則學號就是關鍵字,績點就是值。

下面的Pair類模板就可用來處理這樣的數據記錄:

 

#include <iostream>
#include <string>
using namespace std;
template <class T1,class T2>
class Pair
{
public:
    T1 key;  //關鍵字
    T2 value;  //值
    Pair(T1 k,T2 v):key(k),value(v) { };
    bool operator < (const Pair<T1,T2> & p) const;
};
template<class T1,class T2>
bool Pair<T1,T2>::operator < (const Pair<T1,T2> & p) const
//Pair的成員函數 operator <
{ //"小"的意思就是關鍵字小
    return key < p.key;
}
int main()
{
    Pair<string,int> student("Tom",19); //實例化出一個類 Pair<string,int>
    cout << student.key << " " << student.value;
    return 0;
}

程序的輸出結果是:
Tom 19

實例化一個類模板時,如第 21 行,真實類型參數表中的參數是具體的類型名,如 string、int 或其他類的名字(如 CStudent)等,它們用來一一對應地替換類模板定義中“類型參數表”中的類型參數。類模板名 <真實類型參數表>就成爲一個具體的類的名字。

編譯器編譯到第 21 行時,就會用 string 替換 Pair 模板中的 T1,用 int 替換 T2,其餘部分原樣保留,這樣就自動生成了一個新的類。這個類的名字編譯器是如何處理的不需要知道,可以認爲它的名字就是 Pair <string, int>。也可以說,student 對象的類型就是 Pair<string, int>。

Pair<string, int> 類的成員函數自然也是通過替換 Pair 模板的成員函數中的 T1、T2 得到的。

編譯器由類模板生成類的過程叫類模板的實例化。由類模板實例化得到的類叫模板類。

 

函數模板作爲類模板成員:

類模板中的成員函數還可以是一個函數模板。成員函數模板只有在被調用時纔會被實例化。例如下面的程序:

 

#include <iostream>
using namespace std;
template <class T>
class A
{
public:
    template <class T2>
    void Func(T2 t) { cout << t; }  //成員函數模板
};
int main()
{
    A<int> a;
    a.Func('K');  //成員函數模板Func被實例化
    a.Func("hello");
    return 0;
}

程序的輸出結果是:
Khello

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