Програмування С, С++теорія та практика (частина 2)
2.9.2 Параметризовані класи.
Визначаючи параметризований клас, ми створюємо його каркас (шаблон), що описує усі алгоритми, які використовуються класом. Фактичний тип даних, над яким проводитимуться маніпуляції, буде вказаний в якості параметру при конкретизації об’єктів цього класу. Компілятор автоматично згенерує відповідний об’єкт на основі вказаного типу. Загальна форма декларування параметризованого класу буде такою:
їетріаїе <еіа55 Туре> сіа55 сіа55_пате {
// протокольна частина класу
}
Визначення тіла класу аналогічно звичайному визначенню плюс використанню списку аргументів шаблону. Тип Туре являє собою ім’я типу шаблону, яке в кожному випадку реалізації буде замінюватися конкретним типом даних. Типи можуть бути як стандартні, так і визначені користувачем, для їх опису завжди використовується ключове слово сіазз. При необхідності можливо визначити більше одного параметризованого типу даних, використовуючи їх список через кому. У межах визначення класу шаблонне ім’я можна використовувати у будь-якому місці. Для створення конкретної реалізації використовується наступна форма: сіа55_пате <{уре> оЬ;
У цьому випадку Іуре представляє собою ім’я конкретного типу даних, над якими фактично оперуватиме клас, та замінює змінну Туре. До речі, елементи-функції, над якими оперуватиме клас, автоматично стають параметризованими, тобто їх необов’язково декларувати за допомогою ключового слова ґешріаґе (див. розділ 2.9.1. "Параметризовані функції"). Якщо метод описується за межами шаблону, його заголовок повинен мати наступні елементи: їетріаїе <список_аргументів_шаблону> тип_функц
ім'я_класу <аргументи_шаблону>:: імя_функц (список_пар_функц) {...}
При більш широкому розгляді шаблон класу - узагальнене визначення сімейства класів, яке може використовувати не лише довільні типи, а й константи. Синтаксис його узагальненого опису наступний:
їетріаїе <список_аргументів_шаблону> сіазз ім'я_класу {
// визначення класу
}
Аргумент (список_аргументів_шаблону) може складатися :
• з ключового слова сіазз , за яким слідує ідентифікатор, який визначає параметризований тип (типовий параметр);
• з конкретного імені типу, за яким слідує ідентифікатор
(нетиповий параметр, константа);
Відповідно до кожного з типів параметрів існує два правила використання шаблонів класу. Для створення представника шаблонного класу потрібно вказати ім’я шаблону зі списком аргументів, що заключений у кутові дужки в якості специфікатору типу. Список аргументів модифікується так:
• при використанні аргументів виду нетиповий параметр, тобто «ім ’я типу ідентифікатор» заміна відбувається константним виразом.
• при використанні аргументів виду “типовий параметр”, тобто “сіазз ідентифікатор”, список аргументів модифікується з іменем типу;
Створивши представника шаблонного класу, надалі можливо працювати з ним так само, як з представником звичайного класу.
Приклад 1. Створимо параметризовану чергу із застосуванням в якості аргументу шаблону типового параметру. Головна функція демонструє використання цілих черг та черг з плаваючою комою на основі створеного шаблону класу.
#іпе1ийе "іоз'Ьгеат.Ь"
#іпе1ийе "з £Л1іЬ.Ь"
■Ьетр1а'Ье <с1азз ТуреО> с1азз диеие {
ТуреО *д; іп£ з1ос,г1ос; іп£ 1епд'ЬЬ ; риЬ1іс: диеие(іп£ зіге);
~диеие ()
{
Йе1е^е [] д;
}
Vоій. дз^оге(ТуреО і) ;
// розміщення елемента в кінець черги ТуреО ^^е■Ь^іеVе() ;
// вилучення першого елемента з черги
};
■Ьетр1а'Ье <с1азз ТуреО> диеие<ТуреО>::диеие(іп'Ь зіге)
{
зіге++;
д=пем ТуреО[зіге];
і£ (!д)
{
сои^<<"Неможливо створити чергу!\п"; ехі£(1);
}
1епд'ЬЬ=зіге; з1ос=г1ос=0;
}
^етр1а^е <с1азз ТуреО> VОігі диеие<ТуреО>::дз'Ьоге(ТуреО і)
{
і£ (з1ос+1==1епд'ЬЬ)
{
сои^<<"Черга переповнена!\п"; ге'Ьигп;
}
з1ос++; д[з1ос]=і;
}
^етр1а^е <с1азз ТуреО> ТуреО ^иеие<туре^>::^^е^^іеVе()
{
і£ (г1ос==з1ос)
{
сои^<<"Черга порожня!\п"; ге'Ьигп 0;
}
г1ос++;
ге'Ьигп д[г1ос] ; } іп£ таіп () {
диеие <іп£> а(5), Ь(5); //створення двох черг типу
іп£
a. дз£оге(100);
b. дз£оге(200);
a. дз£оге(300);
b. дз£оге(400);
сои'Ь<< а.^^е^^іеVе()<<" "; сои'Ь<< а.^^е^^іеVе()<<" "; сои'Ь<< Ь.^^е^^іеVе()<<" "; сои'Ь<< Ь.^^е^^іеVе()<<епЛ1;
диеие <£1оа^> £(5), е(5); //створення двох черг типу £1оа£
£.дз£оге(2.12); е.дз£оге(2.99);
£.дз£оге(-30.00); е.дз£оге(1.986); сои'Ь<< £.^^е^^іеVе()<<" "; сои'Ь<< £.^^е■Ь^іеVе()<<" ";
сои'Ь<< е.^^е■Ь^іеVе()<<" "; сои'Ь<< е. ^^е^^іеVе () <<епй1 ; ге'Ьигп 0;
}
Кожна з черг міститься у динамічному масиві, що адресується покажчиком Розмір черги передається як параметр конструктору класу диеие, що зберігається у члені класу іепдґк.. Відповідно змінні гіос та зіос використовуються для індексації черги; перша вказує індекс елементу, що буде вилучений, друга містить адресу, за якою буде збережено наступний елемент. Тип Туре^ можна розглядати як
деякий формальний параметр черги, на місце якого при компіляції
буде підставлено конкретний тип даних.
Приклад 2. Створимо визначення класу із застосуванням в якості аргументу шаблону типового та нетипового параметру. У якості прикладу розглянемо клас, що містить блок пам’яті визначеного типу та довжини.
// параметр шаблону - тип та константа ^етр1а^е <с1азз Туре, іп'Ь зіге> с1азз тето {
рг^а^е:
Туре *р; риЬ1іс: тето ()
{
р=пем Туре[зіге];
}
~тето()
{
йе1е^е [ ] р;
}
орега^ог Туре*() ;
};
^етр1а^е <с1азз Туре, іп'Ь зіге> тето <Туре, зіге> :: орега^ог Туре *()
{
ге'Ьигп р;
}
Створення представника такого класу можливо таким способом: тето<1їоа{, 50> ТіоаІЬіоск;
Константа тут виступає нетиповим параметром. Взагалі у такій якості можуть передаватися змінні цілого та типу перелічення, а також покажчики або посилання на об'єкт або функцію.
Найпоширеніше застосування шаблони класів знаходять при створенні контейнерних класів. Перевага тут у тому, що як тільки логіка, необхідна для підтримки контейнеру, визначена, він може бути застосований до будь-яких типів даних без необхідності будь-якої перебудови. Завдяки цьому одного разу написаний та відлагоджений контейнерний клас можна використовувати повторно. Добре відома бібліотека шаблонів класів фірми Богіапсі, що включає контейнерні класи, які можуть включатися до програм для керування колекціями даних різних типів.
Декілька слів щодо перевантаження шаблонів класу та функцій. В той час, як є можливим перевантаження імен шаблонів функцій, неможливим є цей процес для імен шаблонів класів.
Наприклад, неможливо визначити одночасно Таггау<сІазз Т> та Таггау<сІазз Т, іпґ зігє), в той час як без проблем перевантажуються шаблони функцій. Адже ніщо не завадить описати декілька шаблонів функцій з одним і тим же ім’ям, якщо лише вони мають відмінне число або різний тип параметрів.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
Схожі підручники
- Розрахункова робота з курсу Економыка Пыдприэмства
- Соціальна психологія (частина 3)
- ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 1) онлайн
- Загальні питання з курсу Безпека життєдіяльності №2 (частина 2)
- Структура кредитного портфелю українських банків, недоліки та перспективи покращення
- English_for_Finance_and_Banking
