下面是使用类模板实现的简单栈结构
#include <iostream> using namespace std; template<class T> class myStack { public: myStack(unsigned int size); ~myStack(); void push(T value); T pop(); unsigned int getSize(); private: T *data; unsigned int sp; unsigned int size; }; template<class T> myStack<T>::myStack(unsigned int size) { this->size = size; data = new T[size]; sp = 0; } template<class T> myStack<T>::~myStack() { delete []data; } template<class T> void myStack<T>::push(T value) { data[sp++] = value; } template<class T> T myStack<T>::pop() { return data[--sp]; } template<class T> unsigned int myStack<T>::getSize() { return this->sp; } int main() { myStack<int> ST(10); ST.push(11); ST.push(22); ST.push(33); cout << "count = " << ST.getSize()<< " "; for(unsigned int i = ST.getSize();i > 0 ;--i) { cout << ST.pop() << " "; } return 0; }
模板定义很特殊。由template<…> 处理的任何东西都意味着编译器在当时不为它分配存储空间,它一直处于等待状态直到被一个模板实例告知。
标准要求编译器在实例化模板时必须在上下文中可以查看到其定义实体;
而反过来,在看到实例化模板之前,编译器对模板的定义体是不处理的——原因很简单,编译器怎么会预先知道 typename 实参是什么呢?因此模板的实例化与定义体必须放到同一翻译单元中。
在编译器和连接器的某一处,有一机制能去掉指定模板的多重定义。所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。