Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Oop8.pdf
Скачиваний:
10
Добавлен:
02.02.2015
Размер:
256.31 Кб
Скачать

Зміст

 

Термінологія................................................................................................................................

2

Значення STL..............................................................................................................................

3

Конструкції контейнерів і ітераторів в С++.............................................................................

3

Алгоритми...................................................................................................................................

3

Таблиця контейнерів..................................................................................................................

4

Достоїнства і недоліки програмування з використанням STL...............................................

5

Завдання на лабораторну роботу..............................................................................................

5

Література...................................................................................................................................

7

Тема: STL – стандартна бібліотека шаблонів C++.

Мета: отримати навики роботи із контейнерами і алгоритмами бібліотеки STL; навчитись працювати зі строками С++.

Термінологія

STL (Standard Template Library) – бібліотека мови програмування С++, що базується на шаблонах і виводить С++ на більш високий рівень абстрагування в порівнянні з мовою Сі. Треба розуміти, що STL є невід’ємною частиною С++. Бібліотека входить в стандарт ISO, що описує саму мову.

Контейнер (container) – шаблонний клас, що зберігає об’єкти інших класів. В STL контейнери бувають послідовні (sequence), адаптори (adaptors) та асоціативні (associative).

Послідовний контейнер є таким, у якого розташування елементів можна представити в лінійному порядку. Це динамічний масив (vector), двоспрямований список (list), черга з двома кінцями (deque).

Адаптер – контейнер, який створений (адаптований) на основі вже існуючого послідовного контейнера. Це FIFO черга (queue), LIFO черга (stack), черга з пріоритетом (priority_queue).

Асоціативний контейнер – контейнер, в якому тримаються пари «ключ – значення» (key - value). Іноді називається словник. Значення знаходиться за ключем. Сюди входять відображення (map, multimap), множина (set, multiset). Складність пошуку в такому контейнері оцінюється як O(log(n)).

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

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

Функтор (функціональний об’єкт) – клас, що перевизначає оператор () і надалі поводить себе як звичайна функція. Використовується в алгоритмах для завдання умов обробки контейнерів.

Виняткова ситуація – стан програми після того, як відбулася помилка. Наприклад, оператор new не зміг виділити пам’ять, або якийсь об’єкт звернувся за межі масиву. Виняткові ситуації обробляться в С++ спеціальними конструкціями.

2

Значення STL

Стандартна бібліотека шаблонів (STL) – це набір контейнерів даних, засобів доступу до їхнього вмісту, узагальнених алгоритмів і додаткових об’єктів.

Бібліотека STL спроектована таким чином, щоб можна було повністю відділити подробиці існування даних від загальних алгоритмів, що їх можуть обробляти. Наприклад, бінарне дерево і динамічний масив технічно значно відрізняються один від одного. Але їх можна використати, як параметр для узагальнених функцій count або find, які будуть рахувати кількість вузлів або шукати якийсь конкретний. Узагальненість досягається за рахунок єдиного інтерфейсу доступу до контейнерів – через механізм ітераторів. Простіше кажучи, ітератори – це покажчики на об’єкти.

Конструкції контейнерів і ітераторів в С++

Далі продемонстрований контейнер – динамічний масив або вектор і його константний і звичайний ітератор. Нажаль, тип ітератора має довге ім’я, тому йому краще дати коротший синонім.

//Вектор (динамічний масив) складається із покажчиків на СМС повідомлення.

std::vector<CSmsMessage *> smsVector;

//Практика спрощення запису довгих імен типів

typedef

std::vector<CSmsMessage

*>::iterator

TIterator;

typedef

std::vector<CSmsMessage

*>::const_iterator

TConstIterator;

Наповнення контейнера:

smsVector.push_back( CSmsMessage(message, receiver) );

Доступ до контейнера за ітератором. Більш докладніше потрібно дивитись код в роботі.

for( TConstIterator i = smsVector.begin(); i != smsVector.end(); ++i )

{

std::cout << "text: " << i->Text()

<< "; receiver: " << i->Receiver() << "\n";

}

Про особливості роботи з асоціативними об’єктами потрібно також дивитись код проекту.

Алгоритми

STL включає в себе близько 60 алгоритмів. Основна ідея їх використання: за допомогою ітераторів показати ділянку довільного контейнера, яку треба обробити і операцію з параметром, які треба застосувати на ділянці. Наприклад:

bool IsMessageToMe(const CSmsMessage& aInboxMessage)

{

return aInboxMessage.Receiver() == "to me" ? true : false;

}

3

std::vector<CSmsMessage> inbox;

inbox.push_back( CSmsMessage("How is going?", "to me") );

std::replace_if(

// Для кожного

в inbox

inbox.begin(), inbox.end(),

IsMessageToMe,

//

якщо задовольняється умова, то

CSmsMessage("del it", "del it")

//

замінити на

об'єкт

);

 

 

 

Операції передаються або як покажчики на функції, або через функтори – невеликі класи, що поводять себе як звичайні функції (дивись код в роботі).

Таблиця контейнерів

Послідовні контейнери

vector

C-подібний динамічний масив довільного доступу з автоматичною зміною розміру при

 

додаванні/видаленні елементу. Додавання-видалення елементу в кінець vector займає

 

амортизований O(1) час, та ж операція на початку або середині vector — O(n).

 

 

list

Двоспрямований список, елементи якого зберігаються в довільних ділянках пам'яті, на

 

відміну від контейнера vector, де елементи зберігаються в безперервній області пам'яті.

 

Повільний пошук і доступ за O(n), в будь-якому місці швидка вставка і видалення за

 

O(1).

 

 

deque

Схожий на vector, але з можливістю швидкої вставки і видалення елементів на обох

 

кінцях.

 

 

Асоціативні контейнери

 

 

set

Впорядкована множина унікальних елементів. При вставці/видаленні елементів

 

множини ітератори, що вказують на елементи цієї множини, не стають недійсними.

 

Забезпечує стандартні операції над множиною типу об'єднання, перетину, віднімання.

 

Тип елементів множини повинен реалізовувати оператора порівняння operator< або

 

потрібно надати функцию-компаратор. Реалізований на основі самобалансуючого

 

дерева двійкового пошуку.

 

 

multiset

Те ж що і set, але дозволяє зберігати елементи, що повторюються.

 

 

map

Впорядкований асоціативний масив пар елементів, що складаються з ключів і

 

відповідних ним значень. Ключі повинні бути унікальні. Порядок проходження

 

елементів визначається ключами. При цьому тип ключа повинен реалізовувати

 

оператора порівняння operator<, або потрібно надати функцию-компаратор.

 

 

multimap

Те ж що і map, але дозволяє зберігати ключі, що повторюються.

 

 

Контейнери-адаптери

 

 

 

stack

Стек — контейнер, в якому додавання і видалення елементів здійснюється з одного

 

кінця.

 

 

queue

Черга — контейнер, з одного кінця якого можна додавати елементи, а з іншого —

 

виймати.

 

 

priority_queue

Черга з пріоритетом, організована так, що найбільший елемент завжди стоїть на

 

першому місці.

 

 

Псевдоконтейнери

 

4

 

 

bitset

Служить для зберігання бітових масок. Схожий на vector<bool> фіксованого розміру.

 

Розмір фіксується тоді, коли оголошується об'єкт bitset. Ітераторів в bitset немає.

 

Оптимізований за розміром пам'яті.

 

 

string

Контейнер, призначений для зберігання і обробки рядків. Зберігає в пам'яті елементи

 

підряд єдиним блоком, що дозволяє швидкий доступ до всієї послідовності.

 

 

valarray

Шаблон служить для зберігання числових масивів і оптимізований для досягнення

 

підвищеної обчислювальної продуктивності. В деякій мірі схожий на vector, але в нім

 

відсутня більшість стандартних для контейнерів операцій. Проте, в ньому реалізовані

 

операції, які можна ефективно реалізувати як на векторних процесорах, так і на

 

скалярних процесорах з блоками SIMD.

 

 

Достоїнства і недоліки програмування з використанням STL.

1.STL робить мову програмування С++ високорівневою порівнюючи з майже асемблерним Сі. Програма менш піддається помилкам за рахунок абстрагування від деталей реалізації контейнерів і алгоритмів. В ідеальному випадку програму можна написати взагалі не використовуючи звичайні масиви і покажчики.

2. STL максимально ефективна. Часові штрафи за використання контейнерів або алгоритмів або відсутні, або малі. Контейнери часто не залежать від віртуальних методів.

3.STL може бути розширена (див. [3]).

4.Політика роботи з пам’яттю може бути змінена за рахунок алокаторів (allocators).

5.Код, написаний з використанням STL, не є лаконічним. Наприклад, використання ітераторів незручне.

6.Недоліки шаблонного підходу: великий об’єктний код; час збірки проекту; помилки, які важко читаються.

7.Реалізація STL може сильно залежати від компілятора. Наприклад, час доступу до об’єктів контейнерів в різних реалізаціях може сильно відрізнятися.

Завдання на лабораторну роботу

1.Переробити одну ієрархію ваших класів так, що там використовувались std::vector або std::string. Класи не повинні тримати в собі покажчики на звичайні масиви. Якщо клас має лише один атрибут, зробіть вектор атрибутів. Продемонструйте роботу з переробленими класами. Використовуйте ітератори.

2.За варіантом заповнити контейнери об’єктами своїх класів (один контейнер тримає покажчик на об’єкт; інший – просто об’єкт на стеці).

5

Продемонструйте особливості контейнера. Обробіть контейнер за допомогою алгоритмів. Для *_if алгоритмів використайте функтор. Якщо алгоритм є недоречним до вашого контейнера, поясніть чому і виберіть наступний за варіантом.

Варіант

Послідовний контейнер або

Асоціативний контейнер

Алгоритм

 

строка

 

 

 

 

 

 

1

deque

set

find, count_if

 

 

 

 

2

list

multiset

count, find_if

 

 

 

 

3

vector

map

copy, find_first_of

 

 

 

 

4

string

multimap

transform, replace_copy_if

 

 

 

 

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

6

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]