Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

17.1.7. Приклад створення узагальненої функції abs()

Давайте знову звернемося до функції abs(). Пригадайте, як у розд. 8 стандартні бібліотечні функції abs(), labs() і fabs() були згруповані в три перевантажені функції із загальним іменем myAbs(). Кожна з перевантажених версій функції myAbs() призначена для повернення абсолютного значення для даних "свого" типу. Незважаючи на те, що показане в розд. 8 перевантаження функції abs() можна вважати кроком уперед порівняно з використанням трьох різних бібліотечних функцій (з різними іменами), все ж таки це не кращий спосіб запису функції, яка повертає абсолютне значення заданого аргументу. Оскільки процедура повернення абсолютного значення числа однакова для всіх типів числових значень, то функція abs() може слугувати прекрасним прикладом для створення шаблонної функції. За наявності узагальненої версії функції abs() компілятор зможе автоматично створювати необхідну її версію. Програміст у цьому випадку звільняється від написання окремих версій для кожного типу даних1.

У наведеному нижче коді програми міститься узагальнена версія функції myAbs(). Є сенс порівняти її з перевантаженими версіями, наведеними у розд. 8. Неважко переконатися, що узагальнена версія є коротшою і володіє більшою гнучкістю.

Код програми 17.5. Демонстрація створення узагальненої версії функції myAbs()

#include <vcl>

#include <iostream> // Для потокового введення-виведення

#include <conio> // Для консольного режиму роботи

using namespace std; // Використання стандартного простору імен

template <class aType> aType myAbs(aType num)

{

return num < 0 ? -num : num;

}

int main()

{

cout << myAbs(-10) << "\n"; // Для типу int

cout << myAbs(-10.0) << "\n"; // Для типу double

cout << myAbs(-10L) << "\n"; // Для типу long

cout << myAbs(-10.0F) << "\n"; // Для типу float

getch(); return 0;

}

Для вправи було б непогано, якби Ви спробували знайти інші бібліотечні функції-пре­тен­ден­ти для перероблення їх в узагальнені функції. Необхідно пам'ятати – головне тут те, що один і той самий алгоритм повинен бути застосований до широкого діапазону даних.

17.2. Узагальнені класи

Окрім визначення узагальнених функцій, можна також визначити узагальнений клас. Для цього створюється клас, у якому визначаються всі використовувані ним алгоритми. При цьому реальний тип оброблюваних у ньому даних буде заданий як параметр під час побудови об'єктів цього класу.

Узагальнені класи особливо корисні тоді, коли в них використовується логіка, яку можна узагальнити. Наприклад, алгоритми, які підтримують функціонування черги цілочисельних значень, також надаються і для черги символів. Механізм, який забезпечує підтримку зв'язного списку поштових адрес, також годиться для підтримки зв'язного списку, призначеного для зберігання даних про запчастини до автомобілів. Після створення узагальнений клас зможе виконувати визначену програмістом операцію (наприклад, підтримку черги або зв'язного списку) для будь-якого типу даних. Компілятор автоматично згенерує коректний тип об'єкта на основі типу, що задається під час створення об'єкта.

Загальний формат оголошення узагальненого класу має такий вигляд:

template <class Ttype> class ім'я_класу {

.

.

.

}

У цьому записі елемент Ttype є "заповнювачем" для імені типу, який буде заданий під час реалізації класу. У разі потреби можна визначити декілька узагальнених типів даних, використовуючи перелік елементів, розділених між собою комами.

Створивши узагальнений клас, можна створити його конкретний примірник, використовуючи такий загальний формат:

ім'я_класу <тип> ім'я_об'єкту;

У цьому записі елемент тип означає ім'я типу даних, які оброблятимуться примірником узагальненого класу. Функції-члени узагальненого класу автоматично є узагальненими. Тому програмісту не потрібно використовувати ключове слово template для безпосереднього визначення їх такими.