类模板
模板提供参数化类型,即能够将类型名作为参数传递给接收方来建立类或者函数。例:将类型名int传递给Queue模板,将会让编译器创建一个对int排队的Queue类。
1、定义类模板。
最初的Stack类:
typedef unsigned long Item;
class Stack
{
private:
enum{MAX = 10}; //like #define
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告诉编译器将定义一个模板,而<>中的内容相当于函数的参数列表,可以把关键字class看作变量的类型名,该变量接受类型作为其值。而把Type看作该变量的名称。
使用关键字class并不意味着Type必须是一个类,而是表明Type是一个通用的类型说明符,在使用模板时,将使用实际的类型替换它,也可使用typename替换class。
template <typename Type>
当模板被调用时,Type将被具体的类型值取代(exp: int、string)。在模板定义中,也能使用泛型名标识存储在栈中的类型(即此处的type)。
同样,在成员函数的实现也需使用Type替换上述的Item(假如要实现一个模板Stack类),而相对较为重要的,每个函数头都需要一个相同的模板声明:即上述的tempate<class Type>,而且在Stack::中的作用限定域前加上一个<Type>。
例如:
bool Stack::push(const Item & item)
{}
template<class Type>
bool Stack<Type>::push(const Type & item)
{}
2、使用模板类
模板的具体实现被称为实例化(instantiation)或具体化(specialization),注意,模板并非函数,不能单独编译,必须与特定的模板实例化请求一起使用,最为简单的方法是将所有的模板信息放在一个头文件,并在使用这些模板的文件包含该文件。
因此,仅在程序