Скачать презентацию Ітератори STL Концепція ітераторів Концепцію типу ітератора Скачать презентацию Ітератори STL Концепція ітераторів Концепцію типу ітератора

Les_29_iteratory.ppt

  • Количество слайдов: 29

Ітератори STL Ітератори STL

Концепція ітераторів Концепцію типу ітератора формують три ключові положення: • ітератор забезпечує непрямий доступ Концепція ітераторів Концепцію типу ітератора формують три ключові положення: • ітератор забезпечує непрямий доступ до елементів послідовності; • після інкременту вказує на наступний елемент послідовності; • забезпечує перевірку на співпадіння (рівність) з іншим ітератором.

Особливості ітераторів STL • Відповідність ітераторного типу концепції контейнера : § у векторі – Особливості ітераторів STL • Відповідність ітераторного типу концепції контейнера : § у векторі – це традиційний вказівник на тип контейнерового елемента, тому операції з ітератором еквівалентні операціям з вказівниками § у списку – спеціальний дружній клас, функціональність якого базується на безпосередній роботі з вузлами списку • Уніфікованість контейнерних ітераторів з метою застосовності до різнотипових контейнерів загальних алгоритмів § наявність бібліотечних ітераторних класів, які разом з допоміжними функціями оголошені в просторі назв std, заголовковий файл § надання ітераторам спеціальних властивостей

Категорії ітераторів Ітератор виведення Ітератор введення Ітератор прямий Ітератор двонаправлений Ітератор довільного доступу Категорії ітераторів Ітератор виведення Ітератор введення Ітератор прямий Ітератор двонаправлений Ітератор довільного доступу

Теги стандартних ітераторів //xutility internal header struct output_iterator_tag { output_iterator_tag() {; } }; struct Теги стандартних ітераторів //xutility internal header struct output_iterator_tag { output_iterator_tag() {; } }; struct input_iterator_tag { input_iterator_tag() {; } }; struct forward_iterator_tag : public input_iterator_tag { forward_iterator_tag() {; } }; struct bidirectional_iterator_tag : public forward_iterator_tag { bidirectional_iterator_tag() {; } }; struct random_access_iterator_tag : public bidirectional_iterator_tag random_access_iterator_tag() {; } }; {

Уніфіковані властивості ітераторів template <class Category, class T, class Distance=ptrdiff_t, class Pointer=T*, class Reference=T& Уніфіковані властивості ітераторів template struct iterator// базовий тип для ітераторів { typedef T value_type; typedef Distance difference_type; typedef Pointer pointer; //тип, який повертає operator –>() typedef Reference reference; //тип, який повертає operator *() typedef Category iterator_category; };

Тип характеристик ітераторів template <class Iterator> struct iterator_traits { typedef typename Iterator: : value_type; Тип характеристик ітераторів template struct iterator_traits { typedef typename Iterator: : value_type; typedef typename Iterator: : difference_type; typedef typename Iterator: : pointer; typedef typename Iterator: : reference; typedef typename Iterator: : iterator_category; };

Використання характеристик template <class In. Iter, class T> typename iterator_traits<In>: : difference_type Count (In. Використання характеристик template typename iterator_traits: : difference_type Count (In. Iter first, In. Iter last, const T& val){ typename iterator_traits : : difference_type res=0; while (first!=last) if (*first++ ==val) ++res; return res; }

Категорії ітераторів стандартних класів Операції Категорія, позначення Ітератор введення ( In) Ітератор виведення ( Категорії ітераторів стандартних класів Операції Категорія, позначення Ітератор введення ( In) Ітератор виведення ( Out) Прямий ітератор ( For) Двонаправлений ітератор ( Bi) Ітератор довільного доступу ( Ran) =*p ++ *p= –> == Клас istream_iterator istreambuf_iterator != ostream_iterator ostreambuf_iterator inserter() front_inserter() back_inserter() ++ *p= =*p –> ++ == *p= =*p –> ++ – – != == *p= =*p –> ++ – – + = < > >= != == – = <= != list set і map і multiset multimap Звичайні вказівники С++ vector deque

Генерування ітераторів контейнерами • Для роботи з конкретним контейнером генерується в тісному взаємозв’язку з Генерування ітераторів контейнерами • Для роботи з конкретним контейнером генерується в тісному взаємозв’язку з характерними для типу контейнера класами, напр. , розподілювача пам’яті, вузла списку і т. п. . • Кожен стандартний контейнер автоматично обслуговує функціонування ітераторів. Сукупна система класів, задіяних з цією метою, є достатньо складною, але важливо, що це в основному класи реалізації. • Простота оголошення ітератора, достатньо лише вказати стандартну назву ітераторного типу, вбудованого в його шаблон, і далі використовувати притаманні для цього типу методи. Наприклад, два подібні оголошення vector : : iterator iter 1; list : : iterator iter 2; приводять до утворення ітератора довільного доступу в першому випадку, і двонаправленого в другому.

Ітератори введення, приклад використання - Дозволяють отримати елемент контейнера (=*p) - Не дозволяють змінювати Ітератори введення, приклад використання - Дозволяють отримати елемент контейнера (=*p) - Не дозволяють змінювати елемент контейнера template Input. Iterator find (Input. Iterator first, Input. Iterator last, const T& value) { while (first != last && *first != value) ++first; return first; } Використані операції ітератора введення: !=, *, ++, тому тип ітератора будь-якого контейнера сумісний з типом Input. Iterator

Як ітератори введення можуть використовуватись три види об'єктів: 1) звичайні вказівники: int data[100]; . Як ітератори введення можуть використовуватись три види об'єктів: 1) звичайні вказівники: int data[100]; . . . int * where = find(data, data+10, 7); 2) ітератори контейнерів list a. List; … List: : iterator where = find(a. List. begin(), a. List. end(), 7); 3) ітератори потоків введення, що визначаються класом istream_iterator

class istream_iterator template <class T, class char. T=char, class traits=char_traits<char. T>, class Distance = class istream_iterator template , class Distance = ptrdiff_t> class istream_iterator : public iterator { friend bool operator==(const istream_iterator&x, const istream_iterator& y); protected: istream* stream; T value; bool end_marker; void read (); public: typedef T value_type; typedef char. T char_type; typedef traits_type; typedef istream_type; istream_iterator() : stream(&cin), end_marker(false) {} istream_iterator(istream& s) : stream(&s) { read(); } istream_iterator(const istream_iterator& x ) : stream(x. stream) , value(x. value) , end_marker(x. end_marker) { } const T& operator* () const { return value; } istream_iterator& operator++ (); istream_iterator operator++(int); };

class istream_iterator • Визначає ітератор для вхідного потоку istream (сіn чи файл) • Дозволяє class istream_iterator • Визначає ітератор для вхідного потоку istream (сіn чи файл) • Дозволяє використовувати вхідний потік як контейнер елементів. • При визначенні об”єкта цього класу потрібно вказати: 1) параметр шаблону - тип елементів, що є в потоці: istream_iterator p; 2) проініціалізувати конкретним потоком або конструктором за замовчуванням : istream_iterator p(cin), pend; p – ітератор на перший елемент потоку pend - ітератор на елемент, що слідує за останнім елементом потоку

без >> istream_iterator<int> is(cin); int i 1=*is; //перший елемент в потоці ++is; int i без >> istream_iterator is(cin); int i 1=*is; //перший елемент в потоці ++is; int i 2=*is; //другий елемент в потоці vector v(10); vector: : iterator ins=v. begin(); ifstream ifs("data. txt"); istream_iterator is(ifs), eostr; remove_copy(is, eostr, ins, 4); //скопіювати у вектор // всі елементи з файлу крім тих, що = 4

Ітератори виведення, приклад використання - Дозволяють змінювати значення елементів контейнера (*p= ) - Не Ітератори виведення, приклад використання - Дозволяють змінювати значення елементів контейнера (*p= ) - Не повертають значення елементів контейнера template Output. Iterator copy (In first, In last, Output. Iterator result) { while (first != last) *result++ = *first++; return result; } - Використані операції ітератора виведення: *, ++, - тип ітератора будь-якого неконстантного контейнера сумісний з типом Output. Iterator, - також вказівник - та об’єкт ostream_iterator

class ostream_iterator template <class T, class char. T =char, class traits =char_traits<char. T>> class class ostream_iterator template > class ostream_iterator : public iterator { protected: ostream* stream; const char* str; // delimiter public: typedef T value_type; typedef char. T char_type; typedef traits_type; typedef ostream istream_type; ostream_iterator(ostream& s) : stream(&s), str(0){} ostream_iterator(ostream& s, const char* c) : stream(&s), str((char *)c){} ostream_iterator( const ostream_iterator& x ) : stream(x. stream) , str(x. str){} ostream_iterator& operator=(const T& value){ *stream << value; if (str) *stream << str; return *this; } ostream_iterator& operator*(){ return *this; } ostream_iterator& operator++(int){ return *this; } };

class ostream_iterator • Це шаблон ітератора виведення для форматованого виведення об’єктів заданого типу в class ostream_iterator • Це шаблон ітератора виведення для форматованого виведення об’єктів заданого типу в потік ostream. • Шаблонний параметр визначає тип елементів, що знаходяться в потоці. Це будь-який тип, для якого перевизначено оператор >> ostream_iterator out(cout); • Захищені поля цього класу є вказівниками на стандартний потік ostream і символ-роздільник (будьякий рядок; за замовчуванням 0 - нема): ostream_iterator intout(cout, “: "); • Нема конструктора за замовчуванням • Запис у потік реалізує операція operator=(): out=“gggg”; intout=23;

begin(in), end; ostream_iterator out(cout, "n"); out=“Begin” copy(begin, end," src="https://present5.com/presentation/27526832_238194764/image-19.jpg" alt="без << ifstream in(“data. txt"); istream_iterator begin(in), end; ostream_iterator out(cout, "n"); out=“Begin” copy(begin, end," /> без << ifstream in(“data. txt"); istream_iterator begin(in), end; ostream_iterator out(cout, "n"); out=“Begin” copy(begin, end, out); out = “Еnd!"; - На консоль (потік cout) виведеться спочатку “Begin”, далі послідовність рядків - вміст файлу data. txt. Далі виведеться “End!”. - Розділюючим рядком є "n“.

Ітератори вставки • Для роботи з контейнерами, які мають методи вставки елементів, передбачено шаблони Ітератори вставки • Для роботи з контейнерами, які мають методи вставки елементів, передбачено шаблони спеціальних ітераторів вставки: - insert_iterator - front_insert_iterator - back_insert_iterator • Використовуються в тих алгоритмах, де вимагається вставка елементів. • Додають нові елементи і виконують автоматичний розподіл пам’яті, гарантуючи, що вставлені елементи додадуться до контейнера

class insert_iterator template <class Container> аргумент шаблону – тип контейнера class insert_iterator : public class insert_iterator template аргумент шаблону – тип контейнера class insert_iterator : public iterator { private: typename Container: : iterator iter; protected: Container* container; public: typedef Container container_type; typedef typename Container: : value_type; insert_iterator(Container& x, typename Container: : iterator i) : container(&x), iter(i) {} insert_iterator& operator=(const typename Container: : value_type& value){ iter=container->insert(iter, value); ++iter; return *this; } insert_iterator& operator*(){ return *this; } insert_iterator& operator++ (int){ return *this; } };

class insert_iterator • Конструктор отримує два параметри: - адресу конкретного контейнера - ітератор цього class insert_iterator • Конструктор отримує два параметри: - адресу конкретного контейнера - ітератор цього контейнера, який вказує на місце вставки. • Вставка виконується операцією присвоєння operator=(): - викликається метод insert() контейнера - інкрементується ітератор ++iter

Ітераторна функція inserter() Функція inserter( ) створює ітератор вставки, використовуючи свої аргументи: контейнер Cont Ітераторна функція inserter() Функція inserter( ) створює ітератор вставки, використовуючи свої аргументи: контейнер Cont та ітератор Where template inline insert_iterator inserter(Container& Cont, Iter Where) { // return insert_iterator return (std: : insert_iterator(Cont, Where)); }

Інші ітератори вставки та ітераторні функції • Спеціалізовані на конкретне місце вставки елемента в Інші ітератори вставки та ітераторні функції • Спеціалізовані на конкретне місце вставки елемента в послідовність: клас front_insert_iterator, функція front_inserter( ) – на початок клас back_insert_iterator, функція back_inserter( ) - після останнього елемента • Конструктори класів отримують один аргумент - послідовність (vector, deque, list) і створюють ітератори, які при вставці викликають методи push_front ( ) чи push_back( ), відповідно.

Інші ітератори вставки та ітераторні функції template <class Cont> class back_insert_iterator : public iterator<output_iterator_tag, Інші ітератори вставки та ітераторні функції template class back_insert_iterator : public iterator{. . . }; template class front_insert_iterator : public iterator{. . }; template inline back_insert_iterator back_inserter(Cont& ); template inline front_insert_iterator front_inserter(Cont& );

Ітератори вставки, приклади використання int arr[4] = {3, 4, 7, 8}; vector<int> v(arr, arr+4); Ітератори вставки, приклади використання int arr[4] = {3, 4, 7, 8}; vector v(arr, arr+4); insert_iterator > ins(v, v. begin()+2); ins = 5; Конструктор настроює інсертор на третій елемент вектора ins = 6; операція присвоєння дає змогу вставляти нові елементи Результат v: 3, 4, 5, 6, 7, 8.

 istream_iterator<string> begin(cin), end; vector<string> vs; //copy(begin, end, vs. begin()); // не можна вставляти istream_iterator begin(cin), end; vector vs; //copy(begin, end, vs. begin()); // не можна вставляти // елементи в порожній контейнер copy(begin, end, back_inserter(vs)); copy(vs. begin(), vs. end(), ostream_iterator (cout, ", "));

Прямі ітератори • Об'єднують властивості ітераторів введення та виведення • Допускають як модифікацію, так Прямі ітератори • Об'єднують властивості ітераторів введення та виведення • Допускають як модифікацію, так і доступ до вмістимого контейнера template void replace (Forward. Iterator first, Forward. Iterator last, сonst T& old_value, const T& new_value) { while (first != last) { if (*first == old_value) *first = new_value; ++first; Алгоритм заміни всіх значень old_value на } значення new_value контейнера, } визначеного ітераторами first і last

Двонаправлений ітератор • Додатково підтримує операцію декременту (operator-) • Дає змогу переміщувати ітератор по Двонаправлений ітератор • Додатково підтримує операцію декременту (operator-) • Дає змогу переміщувати ітератор по контейнеру як в прямому, так і в зворотньому напрямку template Output. Iterator reverse_copy (Bidirectional. Iterator first, Bidirectional. Iterator last, Output. Iterator result) { while (first != last) Алгоритм зворотнього копіювання *result++ = *--last; послідовності елементів контейнера, визначеної ітераторами first і last return result; }