Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Контейнери



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

Ми можемо узагальнити стек символів до стека елементів будь-якого типу, оголосивши його як шаблон і замінивши конкретний тип char на параметр шаблону. Наприклад:

template<class T> class stack

{

T* v;

int max_size;

int top;

public:

class Underflow {};

class Overflow {};

class Bad_pop {};

stack(int s);

~ stack();

void push(T);

T pop();

};

Функції-члени можна визначити таким чином:

template<class T> void stack<T>::push(T c)

{

if (top = = max_size) throw Overflow();

v[top]= c;

top = top + 1;

}

template<class T> T stack<T>::pop()

{

if (top = = 0) throw Underflow();

top = top - 1;

return v[top];

}

Після цього стек можна використовувати таким чином:

stack<char> sc(200); // стек для 200 символів

stack<complex> scplx(30); // стек для 30 комплексних чисел

stack<list<int>> sli(45); // стек для 45 списків цілих чисел

void f()

{

sc.push(‘c’);

if (sc.pop()!= ‘c’) throw Bad_pop();

scplx.push (complex(1,2));

if (scplx.pop()!= complex(1,2)) throw Bad_pop();

}

Як шаблони можна визначити списки, вектори і т. д.

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

Стандартна бібліотека шаблонів STL надає найзагальніші й найкорисніші типи контейнерів. Основні| з них перелічені в табл. 8.2

Таблиця 8.2

Основні| контейнери бібліотеки STL

Контейнер Призначення
vector<T> list<T> queue<T> stack<T> deque<T> prioryity_queue<T> set<T> multiset<T>   map<Key, val> multimap<Key, val> Вектор змінного розміру елементів типу <T> Двозвязковий список Черга Стек Черга з двома кінцями Пріоритетна черга Множина Множина, в якій одне значення може зустрічатися кілька разів Асоціативний масив Асоціативний масив, в якому ключ (Key) може зустрічатися кілька разів.

8.4.2 Послідовності та ітератори

У стандартній бібліотеці С++ STL визначене поняття послідовності елементів і є механізм маніпулювання послідовностями за допомогою ітераторів.

Графічне представлення послідовності показано на мал. 8.1

Малюнок 8.1 Графічне представлення послідовності з бібліотеки STL

Послідовність має початок і кінець. Ітератор посилається на поточний елемент і надає операцію, що примушує його посилатися на наступний елемент послідовності. Кінцем послідовності є ітератор, що посилається на елемент, наступний за останнім елементом послідовності.

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

Для доступу до поточного елементу послідовності через ітератор в мові С++ використовується оператор розіменування| * (dereference), а оператор збільшення ++ використовується для того, щоб примусити ітератор посилатися на наступний елемент.

8.4.3 Узагальнені алгоритми

Щоб продемонструвати роботу узагальненого алгоритму, спочатку напишемо наступний код:

template<class In, class Out> void copy(In from, In too_far, Out to)

{

while (from!= too_far)

{

*to = *from; // копіювання елементу, на який

// указує ітератор

++to; // перехід на наступний елемент контейнера

// у який іде копіювання

++from; // перехід на наступний елемент контейнера

// з якого йде копіювання

}

}

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

char vc1[200];

char vc2[500];

void f()

{

copy(&vc1[0] &vc1[200], &vc2[0]);

}

Всі контейнери стандартної бібліотеки С++ підтримують техніку ітераторів і послідовностей.

Два параметри шаблону In і Out використовуються для завдання типів джерела і приймача, оскільки вони можуть бути різними. Наприклад:

complex ас[200];

void g(vector<complex>&vc, list<complex>&lc)

{

copy(&ас[0] &ac[200], lc.begin());

copy(lc.begin(), lc.end(), vc.begin());

}

Ця функціякопіює масив у список і список у вектор. В стандартному контейнері begin() – це ітератор, що вказує на його перший елемент, end() – на елемент, наступний за останнім елементом.

У табл. 8.3 перелічені основні| узагальнені алгоритми бібліотеки STL.

Таблиця 8.3

Основні| узагальнені алгоритми бібліотеки STL

Функція Опис
for_each()     find()   find_if()   count()   replace() replace_if()   copy() unique_copy() sort() merge() Викликає функцію, задану як третій аргумент, для кожного елементу послідовності; має наступний список аргументів: sh.begin(), sh.end(), fun(…) Знаходить у послідовності перше входження аргументу Знаходить у послідовності першу відповідність предикату Підраховує число входжень елементу в послідовність Замінює елемент послідовності новим значенням Замінює елемент послідовності, відповідний предикату, новим значенням Копіює елементи послідовностей Копіює тільки різні елементи послідовностей Сортує елементи послідовностей Зливає відсортовані послідовності

Часто доводиться працювати з контейнером вказівників і бажано викликати функції-члени об'єктів, на які вони посилаються, а не функції над вказівниками. Наприклад, нам може знадобитися викликати функцію-член| shape::draw() для кожного елементу списку list<shape*>. Для вирішення цього завдання можна написати функцію – не член класу, яка викликатиме функцію-член| класу. Наприклад:

void draw(shape* p)

{

p->draw();

}

void f(list<shape*>&sh)

{

for_each(sh.begin(), sh.end(), draw);

}

або натомість:

void g(list<shape*> &sh)

{

for_each(sh.begin(), sh.end(), mem_fun(&shape::draw));

}

Стандартний бібліотечний шаблон mem_fun() приймає як аргумент вказівник на функцію-член і повертає те, що виробляє ця функція.

Механізм mem_fun() важливий, оскільки дозволяє використовувати стандартні алгоритми для контейнерів з поліморфними об'єктами.

9 СИСТЕМА ВВОДУ-ВИВОДУ МОВИ C++

Система вводу - виводу мови C++ так само, як і система вводу - виводу мови C, діє через потоки вводу – виводу.

Потік вводу - виводу — це логічний пристрій, який видає і приймає призначену для користувача інформацію. Потоки вводу – виводу (streams) мови C++ не слід плутати з потоками інструкцій програми (threads), паралельно виконуваними операційною системою.

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

Наприклад, функція, яка використовується для запису інформації на екран комп'ютера, цілком підійде як для запису інформації у файл на диску, так і для виводу її на принтер.





Дата публикования: 2014-11-03; Прочитано: 1003 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.009 с)...