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

22.1. Огляд стандартної бібліотеки шаблонів

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

Ядро стандартної бібліотеки шаблонів містить три основні елементи: контейнери, алгоритми і ітератори. Вони працюють спільно один з іншим, надаючи тим самим користувачу готові розв'язки різних задач програмування.

Контейнери – це об'єкти, які містять інші об'єкти.

Існує декілька різних типів контейнерів. Наприклад, клас vector визначає динамічний масив, клас queue створює двосторонню чергу, а клас list забезпечує роботу з лінійним переліком. Ці контейнери називають послідовними контейнерами і є базовими в бібліотеці STL. Окрім базових, бібліотека STL визначає асоціативні контейнери, які дають змогу ефективно знаходити потрібні значення на основі заданих ключових значень (ключів). Наприклад, клас map забезпечує зберігання пар "ключ-значення" і надає можливість знаходити значення за заданим унікальним ключем.

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

Алгоритми обробляють вміст контейнерів.

Їх можливості містять засоби ініціалізації, сортування, пошуку і перетворення вмісту контейнерів. Багато алгоритмів працюють із заданим діапазоном елементів контейнера.

Ітератори подібні до покажчиків.

Ітератори – це об'єкти, які тою чи іншою мірою діють подібно до покажчиків. Вони дають змогу циклічно здійснювати запит до вмісту контейнера практично так само, як це робиться за допомогою покажчика під час циклічного запиту елементів масиву. Існує п'ять типів ітераторів.

Табл. 22.1. Типи ітераторів

Ітератори

Опис

Довільного доступу (random access)

Зберігають і зчитують значення; дають змогу організувати довільний доступ до елементів контейнера

Двоспрямовані (bidirectional)

Зберігають і зчитують значення; забезпечують інкрементно-декрементне переміщення

Односпрямовані (forward)

Зберігають і зчитують значення; забезпечують тільки інкрементне переміщення

Вхідні (input)

Зчитують, але не записують значення; забезпечують тільки інкрементне переміщення

Вихідні (output)

Записують, але не зчитують значення; забезпечують тільки інкрементне переміщення

У загальному випадку ітератор, який має великі можливості доступу, можна використовувати замість ітератора з меншими можливостями. Наприклад, односпрямованим ітератором можна замінити вхідний ітератор.

Ітератори обробляються аналогічно до покажчиків. Їх можна інкрементувати і декрементувати|. До них можна застосовувати оператор перейменування адреси *. Ітератори оголошуються за допомогою типу iterator, що визначається різними контейнерами.

Бібліотека STL підтримує реверсивні ітератори, які є або двоспрямованими, або ітераторами довільного доступу, даючи змогу переміщатися по послідовності у зворотному порядку. Отже, якщо реверсивний ітератор вказує на кінець послідовності, то після інкрементування він вказуватиме на елемент, розташований перед кінцем послідовності.

При посиланні на різні типи ітераторів у описах шаблонів у цьому навчальному посібнику буде використано такі терміни:

Термін

Наданий ітератор

BiIter

Двоспрямований

ForIter

Односпрямований

InIter

Вхідний

OutIter

Вихідний

RandIter

Довільного доступу

Бібліотека STL опирається не тільки на контейнери, алгоритми і ітератори, але і на інші стандартні компоненти. Основними з них є розподільники пам'яті, предикати і функції порівняння.

Розподільник пам'яті керує виділенням пам'яті для контейнера.

Кожен контейнер має свій розподільник пам'яті (allocator). Розподільники керують виділенням пам'яті для контейнера. Стандартний розподільник – це об'єкт класу allocator, але у разі потреби (у спеціалізованих додатках) можна визначати власні розподільники. Здебільшого стандартного розподільника є цілком достатньо для реалізації програмних задумів.

Предикат повертає як результат значення ІСТИНА/ФАЛЬШ.

Деякі алгоритми і контейнери використовують спеціальний тип функції, так званий предикат (predicate). Існує два варіанти предикатів: унарний і бінарний. Унарний предикат приймає один аргумент, а бінарний – два. Ці функції повертають значення ІСТИНА/ФАЛЬШ, але точні умови, які примусять їх повернути дійсне або помилкове значення, визначаються програмістом. В іншій частині цього розділу, коли знадобиться унарна функція-предикат, на це буде вказано за допомогою типу UnPred. У разі потреби використання бінарного предиката застосовуватиметься тип BinPred. У бінарному предикаті аргументи завжди розташовані у порядку перший, другий стосовно функції, яка викликає цей предикат. Як для унарного, так і для бінарного предикатів аргументи повинні містити значення, тип яких збігається з типом об'єктів, які зберігає цей контейнер.

Функції порівняння порівнюють два елементи послідовності.

Деякі алгоритми і класи використовують спеціальний тип бінарного предиката, який порівнює два елементи. Функції порівняння повертають значення true, якщо їх перший аргумент менший від другого. Функції порівняння ідентифікуються за допомогою типу Comp.

Крім заголовків, потрібних різними класами STL, стандартна бібліотека C++ містить заголовки <utility> і <functional>, які забезпечують підтримку STL. Наприклад, у заголовку <utility> визначається шаблонний клас pair, який може зберігати пару значень. Будемо використовувати клас pair нижче у цьому розділі.

Шаблони у заголовку <functional> дають змогу створювати об'єкти, які визначають функцію operator(). Ці об'єкти називаються об'єктами-функціями, і їх у багатьох випадках можна використовувати замість покажчиків на функції. Існує декілька вбудованих об'єктів-функцій, оголошених у заголовку <functional>. Наведемо тут деякі з них:

plus

minus

multiplies

divides

modulus

negate

equal_to

not_equal_to

greater

greater_equal

less

less_equal

logical_and

logical_or

logical_not

Можливо, найширше використовується об'єкт-функція less, який визначає, за яких умов один об'єкт менший від іншого. Об'єкти-функції можна використовувати замість реальних покажчиків на функції в алгоритмах бібліотеки STL, про які піде мова нижче. Використовуючи об'єкти-функції замість покажчиків на функції, бібліотека STL у деяких випадках генерує ефективніший програмний код.

Матеріал цього розділу не передбачає використання об'єктів-функцій, і ми не застосовуватимемо їх безпосередньо. Детальний опис об'єктів-функцій можна знайти в книзі Герберта Шілдта "Полный справочник по C++" [27].