Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпора II Sem.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
680 Кб
Скачать
☆

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

Узагальнені функції подібні до перевизначених функцій, але мають більше обмежень з їх застосування. При перевизначенні функцій в тілі кожної з них зазвичай записують різні дії. Але узагальнена функція повинна виконувати одні і тісамі дії для всіх її версій; відмінність між версіями полягає тільки в типі оброблюваних даних. Розглянемо приклад, у якому перевизначені функції не можна замінити узагальненою функцією, оскільки вони виконують різні дії:

void outdata(int i)

{

cout << i << endl;

}

void outdata(double d)

{

cout << d * 3.1416 << endl;

}

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

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

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

Демонстрація механізму створення узагальненої версії функції, яка повертає абсолютне значення числа

#include <vcl>

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

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

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

template <class aType> aType myAbs(aType n)

{

return n < 0 ? -n : n;

}

int main()

{

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

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

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

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

getch(); return 0;

}

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

7.2. Поняття про узагальнені класи

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

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

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

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

// Тіло класу

};

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

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

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

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