Обычные классы мы разделяли на интерфейс и реализацию, помещая интерфейс в модуль с расширением h. Этот модуль потом и подключается к другим файлам проекта оператором #include, а реализация класса просто включается в проект.
Попробуем аналогичным образом поступить и с классами-шаблонами. Разделим наш шаблон стека на две части: определение и реализацию (листинг 13.10).
Листинг 13.10. «Определение» шаблона стека
файл TSTACK.h
#ifndef TSTACK #define TSTACK #include <exception> template <class T> class TStack { struct Elem { T data;
Elem *next;
Elem (const T& d, Elem *p) : data(d). next(p) { }
};
Elem * Head; int count;
TStack(const TStack &); // закрыли копирование
TStack& operator=(const TStack &); // закрыпи присваивание
public:
class Error: public std::exception { }; TStackO ;
void push(const T& d); T top() const ; T pop();
bool emptyO const; int count() const;
>:
#endif
// - - файл TSTACKDEF.h
#include "TStack.h" // "подключение" определения
template <class T>
TStack<T>::TStack(): Head(0), count(0) {} template <class T> void TStack<T>::push(const T& d) { Head = new Elem(d, Head); ++count; } template <class T> T TStack<T>::top() const { if(!empty()) return Head->data; else throw Error();
}
template <class T> T TStack<T>::pop() { 1f (emptyO) throw ErrorO; T top = Head->data;
Elem *oldHead = Head; Head = Head->next;
delete oldHead; --count; return top;
}
template <class T>
bool T5tack<T>::empty() const { return Head==0; } template <class T>
int TStack<T>::count() const { return count; }
Как видите, чисто формально этот код ничем не отличается от кода обычного класса TStack (см. листинги 13.5 и 13.6). Третьим модулем в проект включается функция main(), в которой мы наш шаблон стека попытаемся использовать (листинг 13.11). |