c++ Primer Plus讀書筆記——類模板
下面是一段類宣告:
typedef unsigned long Item
class Stack
{
private:
enum { MAX = 10 };
Item items[MAX];
int top;
public:
Stack();
bool isempty() const;
bool isfull() const;
bool push(const Item &item);
bool pop()(Item &item);
};
採用模板時,將使用模板定義替換Stack宣告,使用模板成員函式替換Stack的成員函式。和模板函式一樣採用下面這樣的程式碼開頭:
template <class Type>
關鍵字template告訴編譯器要定義一個模板,較新的c++實現允許用typename代替class,template <typename Type>,我們可以泛型名字代替Type。
所以對於Stack類來說,Item items[MAX]; 應該改成 Type items[MAX];同樣,可以使用模板成員函式替換原有類的方法:
bool Stack::push(const Item &item)
{
...
}
應該改成:
template <class Type>
bool Stack<Type>::push(const Type &item)
{
...
}
如果在類宣告中定義了方法(內聯定義),則可以省略模板字首和類限定符。由於模板不是函式,他們不能單獨編譯。模板必須與特定的模板例項化請求一起使用。為此,最簡單的辦法是將所有模板資訊放在一個頭檔案中,並要使用這些模板的檔案中包含該標頭檔案。
模板類宣告:
//stacktp.h -- a stack template #ifndef STACKTP_H_ #define STACKTP_H_ template <class Type> class Stack { private: enum { MAX = 10 }; Type items[MAX]; int top; public: Stack(); bool isempty(); bool isfull(); bool push(const Type &item); bool pop(Type &item); }; template <class Type> Stack<Type>::Stack() { top = 0; } template <class Type> bool Stack<Type>::isempty() { return top == 0; } template <class Type> bool Stack<Type>::isfull() { return top == MAX; } template <class Type> bool Stack<Type>::push(const Type &item) { if (top < MAX) { item[top++] = item; return true; } else { return false; } } template <class Type> bool Stack<Type>::pop(Type &item) { if (top > 0) { item = items[--top]; return true; } else { return false; } } #endif
使用模板類:
僅在程式包含模板並不能生成模板類,而必須請求例項化。為此,需要宣告一個型別為模板類的物件,方法是使用所需的具體型別替換泛型名。例如,下面的程式碼建立兩個棧,一個用於儲存int,另一個用於儲存string物件:
Stack<int> kernels;
Stack<string> colonels;
編譯器按照Stack<Type>模板來生成兩個獨立的類宣告和兩組獨立的類方法。泛型識別符號——這裡的Type稱為型別引數(type parameter),這意味著他們類似於變數,但是賦給他們的不能是數字,只能是型別。注意,必須顯示的提供所需的型別,這與常規的函式模板時不同的,因為編譯器可以根據函式引數型別來確定要生成哪種函式:
template <class T>
void simple(T t) { cout << t << '\n'; }
...
simple(2); //這裡會使用void simple(int);
simple("two");//這裡會使用void simple(const char *);