上文簡述了C++模板中的函數模板的格式、實例、形參、重載、特化及參數推演,本文主要介紹類模板.
一、類模板格式
類模板也是C++中模板的一種,其格式如下:
template<class 形參名1, class 形參名2, ...class 形參名n>
class 類名{
...
};
例如:我個人模擬實現的Vector的聲明
template<typename T>
class Vector{
public:
typedef T* Iterator; //迭代器
typedef const T* ConstIterator; //const類型迭代器
public:
//類的成員函數
Vector(); //構造函數
Vector(const Vector&); //拷貝構造
Vector& operator=(const Vector&); //賦值運算符重載
~Vector(); //析構函數
public:
//公共接口
void PushBack(const T &); //尾插
void PopBack(); //尾刪
Iterator Find(const T &); //查找
void Insert(Iterator*); //插入
void Erase(Iterator*); //刪除
void Size(); //獲取有效元素個數
bool Empty(); //判斷是否為空
void clear(); //清空
public:
//迭代器接口
Iterator Begin(); //迭代器起始位置
Iterator End(); //迭代器結束位置
private:
T *_start;
T *_finish;
T *_endOfStroage;
};
二、模板類的實例化
只要有不同的類型,編譯器就會實例化出一個對應的類,這點與函數模板非常相似.例如:
Vector<int> v1; Vector<char> v2;
當定義上述兩個類型的Vector時,編譯器會用int和char分別代替模板形參,重新編寫Vector類,最后創建Vector<int>和Vector<char>類.
三、非類型的模板參數
對於函數模板和類模板,模板參數並不局限於類型,普通值也可以作為模板參數。例如:
template<typename T,int SIZE=10>
class Array{
private:
T _arr[SIZE];
};
雖然非類型模板參數很好用,但是也有一些限制:
注意:浮點數和類對象是不允許作為非類型模板參數的.
***函數模板不支持形參帶默認值.
四、類模板的特化
模板的特話分為兩種,全特化和偏特化.
全特化是指,所有的模板參數都要進行特化.例如:
template<typename T>
class Vector{
public:
Vector();
~Vector();
private:
T *_start;
T *_finish;
T *_endOfStroage;
};
template<>
class Vector<int>{
public:
Vector();
~Vector();
private:
int *_start;
int *_finish;
int *_endOfStroage;
}
//不需要模板參數
Vector<int>::Vector(){
//代碼
}
從上述代碼我們可以看出:特化后定義成員函數不需要加模板參數.
偏特化,是指多個模板參數可以只特化一個或一部分.如:
template<typename T1,typename T2>
class Add{
public:
Add();
~Add();
private:
T1 _left;
T2 _right;
};
//只特化第一個參數
template<typename T2>
class Add<int,T2>{
public:
Add();
~Add();
private:
int _left;
T2 _right;
};
//特化指針類型
template<typename T1,typename T2>
class Add<T1*,T2*>{
public:
Add();
~Add();
private:
T1 _left;
T2 _right;
T1* _leftPtr;
T2* _rightPtr;
};
我們從上述代碼可以看出,偏特化具有這樣的特性:
偏特化並不僅僅局限於特化部分參數,而是對模板參數更進一步的條件限制所設定出來的一個特化版本.
最后的說明:
特化並不只是類模板才具有的特性,函數模板也具有特化功能,函數模板的特化與類模板類似.
