Elem * Head; int count;
TStack(const TStack &); // закрыли копирование
TStack& operator=(const TStack &); // закрыли присваивание public:
class Error: public std::exception { };
TStackO;
-TStackQ ;
void push(const T& d); T top() const ; T pop();
bool emptyO const; int countO const;
}:
//- определение методов
template <class T>
TStack<T>::TStack(): Head(0). count(0) {}
template <class T> // шаблон
TStack<T>::~TStack() // прототип
{ while(!empty()) // тело
{ T t = pop(); }
}
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() { if (emptyO) throw Error(); T top = Head->data;
Elem *oldHead = Head; Head = Head->next; delete oldHead; --count; return top;
}
template <class T>
bool TStack<T>::empty() const
{ return Head==0; }
template <class T>
int TStack<T>::count() const
{ return count; }
В этом случае определение метода тоже должно начинаться со слова template с параметрами шаблона. Тип шаблонного класса TStack<T> задается в качестве префикса. В теле метода, как обычно, все имена класса можно употреблять без префикса.
Резюме
Особую роль при наследовании играют виртуальные функции, которые позволяют изменять поведение методов. С помощью виртуальных методов в С++ реализуется динамический полиморфизм времени выполнения. Виртуальные функции наследуются, их можно перегружать и переопределять. Конструкторы и статические методы не могут быть виртуальными. Виртуальную функцию можно вызывать невиртуально. В конструкторах и деструкторе виртуальность не работает — вызываются только «родные» методы. Наличие в классе виртуальных функций обычно увеличивает размер класса.
Деструкторы тоже могут быть виртуальными. Чистые виртуальные функции не имеют тела. Наличие в классе чистой виртуальной функции делает класс абстрактным; объекты абстрактного класса создавать запрещено, но указатели и ссылки — можно. Абстрактность наследуется. Деструктор тоже может быть чистым, при этом необходимо его определить; «чистота» деструктора не наследуется. Чистую виртуальную функцию тоже можно определить, однако ее «чистота» наследуется — класс-наследник остается абстрактным, если не реализует унаследованную чистую виртуальную функцию.
Для классов в иерархии наследования виртуальные функции позволяют реализовать разное поведение внешних функций, которые даже не являются дружественными. |