Шаблон класса позволяет создавать параметризированный класс. Параметром может быть любой тип или значение одного из допустимого типа. Шаблон класса сам по себе не является ни типом не объектом. Из исходного файла содержащий только определение шаблона не генерируется код.
Компилятор генерирует код только когда из данного шаблона был создан конкретный класс с набором аргументов.
Общая форма объявление похожа на шаблон функции и добавлено только ключевое слово class
Для примера:
template < class T> class имя_класса { }
template < class T>
Рассмотрим небольшой пример реализации стека, который сделан в виде шаблона и позволяет работать с разными типами переменных:
Основной файл с описание класса и его реализацией
// файл “vt.h” #ifndef VT_H #define VT_H #include <QDebug> template <typename T> class Stack { private: T * stack; int size; int top; public: Stack(int size_new) { stack = new T[size_new]; size = size_new; top = -1; } ~Stack() { delete [] stack; } bool push(const T value ) { if (top == size - 1) return false; top++; stack[top] = value; return true; } bool pull() { if (top == - 1) return false; stack[top] = 0; top--; return true; } void qDebugStack() { for (int i = size -1; i >= 0; i--) qDebug() << stack[i]; } }; #endif // VT_H
// функция main #include <QCoreApplication> #include "vt.h" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Благодаря шаблону мы используем один и тот же класс // для значений int Stack <int> StackInt(5); // для значений double Stack <double> StackDouble(10); // заполняем стеки for (int i = 1; i < 6; i++) StackInt.push(i); for (int i = 1; i < 11; i++) StackDouble.push(i); StackInt.qDebugStack(); // выводим значения /* 5 4 3 2 1 */ StackDouble.qDebugStack(); // выводим значения /* 10 9 8 7 6 5 4 3 2 1 */ // Удаляем элементы StackInt.pull(); StackInt.pull(); StackInt.pull(); StackInt.qDebugStack(); // выводим значения /* 0 0 0 2 1 */ StackDouble.pull(); StackDouble.pull(); StackDouble.pull(); StackDouble.pull(); StackDouble.qDebugStack(); // выводим значения /* 0 0 0 0 6 5 4 3 2 1 */ return a.exec(); }
В данном примере реализация входит в классе. При необходимости ее можно вынести в отдельную функцию для этого перед объявлением функции нужно добавить определение шаблона.
Для примера вынесем функция pull
template <class T> bool Stack <T>::pull() { if (top == - 1) return false; stack[top] = 0; top--; return true; }
В самом классе изменим pull на bool pull();