
Бібліотека стандартних шаблонів stl
Окрім ООП в сучасних IDE широко підтримується узагальнене програмування (generic programming), яке спрямоване на спрощення повторного використання коду і на абстрагування загальних концепцій. В узагальненому програмуванні можна один раз написати функцію для узагальненого, тобто невизначеного типу, і потім використовувати її для множини існуючих типів.
Концепція узагальненого програмування допускає використання типів даних як параметрів. При розробці алгоритму, що може працювати із множиною типів і структур даних, використовується якийсь абстрактний тип, що згодом параметризується. Такий підхід забезпечує простий спосіб введення різного роду загальних концепцій і позбавляє програміста від написання вручну спеціалізованого коду.
У мовах програмування узагальнене програмування реалізується за допомогою шаблонів (templates). Шаблон являє собою параметризоване визначення деякого елемента програми. При цьому розроблювач усього лише вказує компілятору правило для генерації (породження) одного або декількох конкретних екземплярів цього елемента програми. Як параметр шаблона можна використовувати тип (клас), звичайний параметр відомого типу, інший шаблон.
Наприклад, функція сортування для даних різних типів (чисел, символів, рядків тощо). Без використання шаблонів довелося б створювати свою функцію для кожного з типів даних, при цьому дуже часто функції розрізнялися б тільки в заголовку і типах локальних змінних.
Окрім можливості визначення власних користувацьких шаблонів, сучасні IDE надають у розпорядження розробника стандартні бібліотеки шаблонів. Для мови С++ такою є бібліотека STL (Standard Template Library), яка містить універсальні шаблонні класи та функції, які реалізують функціональність багатьох часто використовуваних структур даних і деяких узагальнених алгоритмів (сортування, пошуку мінімального та максимального значення тощо).
Ядро бібліотеки утворюють три складові:
контейнери,
алгоритми,
ітератори.
Контейнери – це об'єкти STL, що зберігають інші елементи і реалізують механізми доступу до них. Тут представлені різні варіанти часто використовуваних структур даних: vector (динамічний масив або вектор), string (рядок), set (множина), list (список) і т.ін. Якщо бути більш точними, то контейнери – це навіть не самі структури, а заготовки для них. Конкретну структуру для свого типу даних програміст утворює за допомогою стандартних контейнерів сам.
Кожен контейнер описується шаблонним класом, у якому реалізуються механізми доступу і функції для обробки елементів, що містяться у контейнері. При цьому тип елемента задається параметром шаблона. Для використання контейнерів необхідно підключити однойменний заголовний файл, наприклад, <set> - для множин.
Для створення будь-якого з контейнерів може бути використаний конструктор за замовчуванням (у цьому випадку створюється порожній контейнер), конструктор копіювання, конструктор, який ініціалізує контейнер діапазоном елементів іншого контейнера (не обов'язково того ж типу):
container<T> k;
container<T> k1(c);
container<T> k2(b,e);
Тут container – будь-який з типів контейнерів STL; T - тип елементів контейнера; k, k1, k2 – утворені контейнери.
Всі контейнери розроблені таким чином, щоб при необхідності можна було працювати з їх елементами незалежно від того, у якому саме різновиді контейнера – векторі, списку, чи черзі – ці елементи зберігаються. Зрозуміло, що різновиди контейнерів розрізняються між собою і внутрішнім устроєм, і ефективністю різних операцій, і набором додаткових, характерних тільки для них, способів доступу до елементів. Наприклад, у вектора є оператор індексування [ ], якого немає у списків, проте список дозволяє ефективно виконувати операції вставки і видалення елементів. Але при цьому кожен з контейнерів підтримує набір однотипних операцій – невеликий, але достатній для того, щоб на його основі можна було писати узагальнені алгоритми для роботи з елементами.
Основні методи, які присутні в усіх контейнерах STL, представлені в табл. 1.
Таблиця 1. Основні методи контейнерів STL
Назва |
Опис |
empty |
визначає, чи є колекція порожньою |
size |
визначає розмір колекції |
clear |
видаляє всі елементи колекції |
erase |
видаляє елемент або декілька елементів з колекції |
Ітератори — це об'єкти STL, що реалізують концепцію інтелектуального вказівника і дозволяють одержати доступ до елементів контейнера. Ітератори бувають різних типів: для переміщення у контейнері тільки вперед (прямий ітератор), тільки в зворотньому напрямку (зворотний ітератор) тощо.
Таблиця 2. Основні методи роботи з ітераторами
Назва |
Опис |
begin |
повертає прямий ітератор, який вказує на початок контейнера |
end |
повертає прямий ітератор, який вказує на кінець контейнера(реально він вказує на уявний неіснуючий елемент, наступний за останнім) |
rbegin |
повертає зворотний ітератор, який вказує на останній елемент контейнера |
rend |
повертає зворотний ітератор, який вказує на початок контейнера(на уявний неіснуючий елемент, що передує першому елементу) |
Оскільки ітератор є аналогом вказівника, до нього можна застосовувати ті ж самі операції, що і до звичайного вказівника: розіменування, інкремента, декремента і порівняння. Для використання ітераторів слід підключити заголовний файл <iterator>.
Для виконання деяких типових дій над елементами, що містяться у контейнері, використовуються глобальні алгоритми, як складові STL-бібліотеки. Основними алгоритмами є заповнення контейнера за відповідним правилом, сортування за вказаним критерієм, пошук за заданим критерієм, заміна елементів контейнера. Алгоритми визначені в заголовному файлі <algorithm>.
Слід зазначити, що алгоритми не є частиною контейнерів, а утворюють окрему колекцію2. Але при цьому майже будь-який алгоритм може застосовуватися до майже будь-якого контейнера. При використанні деякого алгоритма для обробки деякого контейнера, цей контейнер передається в якості параметра.