![](/user_photo/2706_HbeT2.jpg)
- •Лабораторна робота № 33
- •Тема: Шаблони (параметризовані типи).
- •Мета: вивчити представлення та правила роботи із шаблонами.
- •Теоретична частина
- •Шаблони функцій
- •Вимоги до фактичних параметрів шаблону
- •Ототожнення типів аргументів
- •Шаблони класів
- •Шаблони класів : не лише для типів
- •Успадкування в шаблонах класів
- •Контрольні питання
- •Порядок виконання лабораторної роботи
- •Вимоги до звіту
- •Варіанти завдань
Шаблони класів
Ви можете створювати шаблони і для класів, що дозволяє так же красиво працювати з будь-якими типами даних. Класичним прикладом є контейнерні класи (тобто класи, що містять типи), наприклад множини. Використовуючи шаблон, можна створювати родовий клас для множин, після чого породжувати конкретні множини - кольорів, рядків і так далі.
Спочатку розглянемо приклад. Приклад, що розглядається далі, - клас, який зберігає пару значень. Функції-елементи цього класу повертають мінімальне і максимальне значення, а також дозволяють визначити, чи є два значення однаковими. Оскільки перед нами шаблон класу, то тип значення може бути майже будь-ким.
template <class T>
class Pair
{ T a, b;
public:
Pair (T t1, T t2);
T Max();
T Min ();
int isEqual ();
};
Поки усе виглядає також витончено, як і для шаблонів функцій. Єдина різниця полягає в тому, що замість опису функції використовується оголошення класу. Шаблони класів стають усе більш складними, коли ви описуєте належні функції класу. Ось, наприклад, опис належної функції Min() класу Pair :
template <class T>
T Pair <T>::Min()
{ return a < b ? a: b;
}
Щоб зрозуміти цей запис, давайте повернемося небагато назад. Якби Pair був звичайним класом (а не шаблоном класу) і T був би деяким конкретним типом, то функція Min класу Pair була б описана таким чином:
T Pair::Min()
{ return a < b ? a: b;
}
Для випадку шаблонної версії нам необхідно, по-перше, додати заголовок шаблону template <class T>
Потім треба дати ім'я класу. Пам'ятайте, що насправді ми описуємо безліч класів - сімейство Pair. Повторюючи синтаксис префікса (заголовка) шаблону, екземпляр класу Pair для цілих типів, можна назвати Pair<int>, екземпляр для типу double - Pair<double>, для типу Vector - Pair<Vector>. Проте в описі що належить класу функції нам необхідно використовувати ім'я класу Pair<T>. Це має сенс, оскільки заголовок шаблону говорить, що Т означає ім'я будь-якого типу.
Приведемо текст інших методів класу Pair. Описи методів поміщаються в заголовний файл, оскільки вони має бути видимі скрізь, де використовується клас Pair.
// // конструктор
template <class T>
Pair <T>::Pair (T t1, T t2) : a(t1), b(t2)
{}
// // метод Max
template <class T>
T Pair <T>::Max()
{ return a>b ? a: b;
}
// // метод isEqual
template <class T>
int Pair <T>::isEqual()
{ if (a==b) return 1;
return 0;
}
Раніше вже відзначалося, що шаблони функцій можуть працювати тільки для тих (вбудованих) типів даних або класів, які підтримують необхідні операції. Те ж саме справедливе і для шаблонів класів. Щоб створити екземпляр класу Pair для деякого класового типу, наприклад для класу X, цей клас повинен містити наступні загальнодоступні функції
X (X &); // конструктор копіювання
int operator == (X)
int operator < (X);
Три вказані функції потрібно, оскільки вони реалізують операції, що виконуються над об'єктами типу T в методу X шаблону класу Pair.
Якщо ви збираєтеся використовувати деякий шаблон класу, як упізнати які операції вимагаються? Якщо шаблон класу забезпечений документацією, то ці вимоги мають бути в ній вказані. Інакше доведеться читати первинну документацію - початковий текст шаблону. При цьому враховуйте, що вбудовані типи даних підтримують усі стандартні операції.