- •7. Робота з шаблонними, функціями та класами
- •7.1. Поняття про узагальнені функції
- •7.1.1. Механізм реалізації шаблонної функції з одним узагальненим типом
- •7.1.2. Безпосередньо задане перевизначення узагальненої функції
- •7.1.3. Шаблонна функція з двома узагальненими типами
- •7.1.4. Механізм перевизначення специфікації шаблону функції
- •7.1.5. Використання стандартних параметрів у шаблонних функціях
- •7.2. Поняття про узагальнені класи
- •7.1.6. Обмеження, які застосовуються при використанні узагальнених функцій
- •7.1.7. Приклад створення узагальненої функції abs()
- •7.2.1. Створення класу з одним узагальненим типом даних
- •7.2.2. Створення класу з двома узагальненими типами даних
- •7.2.3. Приклад створення узагальненого класу для організації безпечного масиву
- •7.2.4. Використання в узагальнених класах аргументів, що не є узагальненими типами
- •11.2.1. Передача покажчиком на функцію її адреси іншій функції
- •9.2.3. Класи потоків
- •9.3. Особливості механізмів перевизначення операторів введення-виведення даних
- •9.3.1. Створення перевизначених операторів виведення даних
- •9.5. Організація файлового введення-виведення даних
- •9.5.1. Відкриття та закриття файлу
- •9.5.2. Зчитування та запис текстових файлів
- •9.5.3. Неформатне введення-виведення даних у двійковому режимі
- •9.5.4. Зчитування та записування у файл блоків даних
- •10. Динамічна ідентифікація типів і оператори приведення типу
- •10.1. Динамічна ідентифікація типів
- •10.1.1. Отримання типу об'єкта у процесі виконання програми
- •10.1.2. Приклад rtti-застосування
- •11. Поняття про простори імен та інші ефективні програмні засоби
- •11.1. Особливості організації простору імен
- •11.1.1. Поняття про простори імен
- •11.1.2. Застосування настанови using
- •11.1.3. Неіменовані простори імен
- •11.1.4. Застосування простору імен std
- •11.2. Застосування покажчиків на функції
- •11.2.2. Пошук адреси перевизначеної функції
- •11.3. Поняття про статичні члени-даних класу
- •11.5. Застосування до функцій-членів класу модифікаторів const і mutable
- •11.6. Використання explicit-конструкторів
- •12. Введення в стандартну бібліотеку шаблонів
- •12.1. Огляд стандартної бібліотеки шаблонів
- •12.2. Поняття про контейнерні класи
- •12.3. Механізми роботи з векторами
- •12.3.1. Доступ до елементів вектора за допомогою ітератора
- •12.3.2. Вставлення та видалення елементів з вектора
- •12.3.3. Збереження у векторі об'єктів класу
- •12.3.4. Доцільність використання ітераторів
- •7. Робота з шаблонними, функціями та класами 1
- •7.1. Поняття про узагальнені функції 1
- •10. Динамічна ідентифікація типів і оператори приведення типу 26
- •11. Поняття про простори імен та інші ефективні програмні засоби 31
- •12. Введення в стандартну бібліотеку шаблонів 44
7.2.1. Створення класу з одним узагальненим типом даних
У наведеному нижче коді програми клас queueClass перероблений в узагальнений клас з одним узагальненим типом даних. Це означає, що його можна використовувати для організації черги об'єктів будь-якого типу. У цьому прикладі створюються дві черги: для цілих чисел і значень з плинною крапкою, але можна використовувати дані і будь-якого іншого типу.
Демонстрація механізму створення класу з одним узагальненим типом даних
#include <vcl>
#include <iostream> // Для потокового введення-виведення
#include <conio> // Для консольного режиму роботи
using namespace std; // Використання стандартного простору імен
const int size=100;
// Створення узагальненого класу queueClass.
template <class qType> class queueClass {
qType array[size];
int sloc, rloc;
public:
queueClass() { sloc = rloc = 0; }
void Get(qType c);
qType Put(); // Виведення з об'єкта значення
};
// Занесення об'єкта в чергу.
template <class qType> void queueClass<qType>::Get(qType c)
{
if(sloc==size) { cout << "Черга заповнена" << endl; return; }
sloc++;
array[sloc] = c;
}
// Вилучення об'єкта з черги.
template <class qType> qType queueClass<qType>::Put()
{
if(rloc == sloc) { cout << "Черга порожня" << endl; return 0; }
rloc++;
return array[rloc];
}
int main()
{
queueClass<int> ObjA, ObjB; // Створюємо дві черги для int-значень.
ObjA.Get(10);
ObjB.Get(19);
ObjA.Get(20);
ObjB.Get(1);
cout << ObjA.Put() << " ";
cout << ObjA.Put() << " ";
cout << ObjB.Put() << " ";
cout << ObjB.Put() << endl;
queueClass<double> ObjC, ObjD; // Створюємо дві черги для double-значень
ObjC.Get(10.12);
ObjD.Get(19.99);
ObjC.Get(-20.0);
ObjD.Get(0.986);
cout << ObjC.Put() << " ";
cout << ObjC.Put() << " ";
cout << ObjD.Put() << " ";
cout << ObjD.Put() << endl;
getch(); return 0;
}
Внаслідок виконання ця програма відображає на екрані такі результати:
10 20 19 1
10.12 -20 19.99 0.986
У цьому коді програми оголошення узагальненого класу є подібним до оголошення узагальненої функції. Тип даних, який зберігаються в черзі, узагальнений в оголошенні класу. Він невідомий доти, доки не буде оголошений об'єкт класу queueClass, який і визначить реальний тип даних. Після оголошення конкретного примірника класу queueClass компілятор автоматично згенерує всі функції та змінні, необхідні для оброблення реальних даних. У цьому прикладі оголошуються два різних типи черги: дві черги для зберігання цілих чисел і дві черги для значень типу double. Зверніть особливу увагу на ці оголошення:
queueClass<int> ObjA, ObjB;
queueClass<double> ObjC, ObjD;
Зауважте, як вказується потрібний тип даних: він поміщається в кутові дужки. Змінюючи тип даних при створенні об'єктів класу queueClass, можна змінити тип даних, який зберігаються в черзі. Наприклад, використовуючи таке оголошення, можна створити ще одну чергу, яка міститиме покажчики на символи:
queueClass<char *> chrptrQ;
Можна також створювати черги для зберігання даних, тип яких створений програмістом. Наприклад, нехай необхідно використати таку структуру для зберігання інформації про адресу:
struct addrStruct
{ // Оголошення типу структури
char name[40];
char street[40];
char city[30];
char state[3];
char zip[12];
};
Тепер для того, щоби за допомогою узагальненого класу queueClass, можна було згенерувати чергу для зберігання об'єктів типу addrStruct, достатньо використовувати таке оголошення:
queueClass<addrStruct> obj;
На прикладі класу queueClass неважко переконатися, що узагальнені функції та класи є потужними засобами, які допоможуть збільшити ефективність роботи програміста, оскільки вони дають змогу визначити загальний формат об'єкта, який можна потім використовувати з будь-яким типом даних. Узагальнені функції та класи позбавляють Вас від рутинної праці зі створення окремих реалізацій для кожного типу даних, які підлягають обробленню єдиним алгоритмом. Цю роботу зробить за Вас компілятор: він автоматично створить конкретні версії визначеного Вами класу.
