1. 程式人生 > >c++ Primer Plus讀書筆記——類模板

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 *);