上文簡述了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; };
我們從上述代碼可以看出,偏特化具有這樣的特性:
偏特化並不僅僅局限於特化部分參數,而是對模板參數更進一步的條件限制所設定出來的一個特化版本.
最后的說明:
特化並不只是類模板才具有的特性,函數模板也具有特化功能,函數模板的特化與類模板類似.