Top Banner
Бублик Володимир Васильович Програмування - 2 Лекція 11. Ієрархічне програмування. Ітератори в контейнерах Лекції для студентів 2 курсу
50

11 Iterated Containers

Jul 07, 2015

Download

Technology

olegapster
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 11 Iterated Containers

Бублик Володимир Васильович

Програмування - 2

Лекція 11. Ієрархічне програмування.

Ітератори в контейнерах

Лекції для студентів 2 курсу

Page 2: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 2

Повторення. Ітерований список

• class List• {• public:• List();• ~List();• void add(const Elem& elem);• const Elem& get() const;• void begin() const { _current = _start;}• void next() const { _current = _current -> _next; }• bool done() const { return _current == 0; }• };

Page 3: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 3

Питання

• Чи залежить ітератор від самого контейнера? ― Так, оскільки він є частиною класу

Висновок:

• Невдале рішення: для користування ітератором ми повинні точно знати тип контейнера

Page 4: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 4

Вивід списку

• ostream& operator <<(ostream & os, const List& lst)• {• lst.begin();• while (!lst.done())• {• os<<lst.get()<<':';• lst.next();• }• return os;• }

Page 5: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 5

Узагальнений вивід

• template <class Container>• ostream& operator <<(ostream & os, const Container& c)• {• c.begin();• while (!c.done())• {• os<<c.get()<<':';• c.next();• }• return os;• }

Page 6: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 6

Оцінка

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

Page 7: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 7

Аналіз вимог (1)

Функція оперує лише інтерфейсом ітератора• ostream& operator <<(ostream & os, const Itor& it)• {• it.begin();• while (!it.done())• {• os<<it.get()<<':';• it.next();• }• return os;• }

Page 8: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 8

Аналіз вимог (2)

Допускається як читання, так і запис елементів даних до контейнера

• void process (Itor& it)• {• for (it.begin(); !it.done(); it.next()) //C style• {• it.put ( it.get()+1 );• }• return;• }

Page 9: 11 Iterated Containers

1. Індивідуальні контейнери

Page 10: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 10

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

Зберемо інтерфейс в абстрактний клас• class Itor• {• public:• virtual ~Itor(){ };• virtual void begin () const = 0;• virtual const Elem& get () const =0;• virtual void put (const Elem &) = 0;• virtual bool done () const = 0;• virtual void next () const = 0;• };

Page 11: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 11

Неітерований список

• class List• {• public:• List();• ~List();• List& add(const Elem& elem);• void del();• bool empty() const { return _amount==0;}• int amount() const { return _amount;}• private:• List (const List&);• List& operator= (const List&);

Page 12: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 12

Неітерований список

• // Реалізація• protected:• struct Node• {• Elem _elem;• Node * _next;• Node * _prev;• };• Node * _start;• int _amount;• };

Page 13: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 13

Змішування інтерфейсів

• class IteratedList: public Itor, public List• {• private:• mutable Node * _current; // на вузол списку• public:• IteratedList();• virtual void begin () const;• virtual const Elem& get() const;• virtual bool done() const;• virtual void next() const;• virtual void put(const Elem &);• };

Page 14: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 14

Реалізація

• IteratedList :: IteratedList():_current(0)• {• };• const Elem& IteratedList :: get() const• {• return _current->_elem;• }• void IteratedList :: put (const Elem & elem)• {• _current->_elem = elem;• return;• }

Page 15: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 15

Реалізація

• bool IteratedList :: done() const• {• return _current == 0;• }

• void IteratedList :: next() const• {• _current= _current->_next;• return;• }

Page 16: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 16

Масив

• class Array• {• public:• explicit Array (size_t);• ~Array();• Elem& operator[] (size_t index);• const Elem& operator[] (size_t index) const;• size_t size() const;• private:• size_t _size;• Elem * _pElem;• };

Page 17: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 17

Ітерований масив

• class IteratedArray: public Itor, public Array• {• private:• mutable size_t _current;• public:• IteratedArray(size_t n): Array(n){};• virtual void begin () const;• virtual const Elem& get() const;• virtual bool done() const;• virtual void next() const;• virtual void put(const Elem &);• };

Page 18: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 18

Реалізація

• const Elem& IteratedArray::get() const• {• return (*this)[_current];• }• bool IteratedArray::done() const• {• return _current == size();• }• void IteratedArray::put(const Elem & elem)• {• (*this)[_current] = elem; return;• }

Page 19: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 19

Реалізація

• IteratedArray :: IteratedArray (size_t n): Array(n)• {• };• void IteratedArray::begin() const• {• _current = 0; return;• }• void IteratedArray::next() const• {• ++_current; return;• }

Page 20: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 20

Діаграма індивідуальних контейнерів

Page 21: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 21

Сценарій спільного вживання

• // Створення ітерованого списку• IteratedList lst;• lst.add('a').add('b').add('c').add('d');•• // Створення ітерованого масиву• IteratedArray ar(5);• ar[0]='z'; ar[1]='y'; ar[2]='x'; ar[3]='w'; ar[4]='v';

• // Обробка спільною функцією process (Itor &)• process (lst); • process (ar);

Page 22: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 22

Недолік

• Кожен ітератор в силу успадкування містить в собі екземпляр контейнера. Виникає проблема використання кількох ітераторів в межах одного контейнера (особливо за умови закритого копіювання контейнерів)

Page 23: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 23

Питання

• Чи потрібен ітераторам інтерфейс списку і, відповідно, інтерфейс масиву?

Page 24: 11 Iterated Containers

2. Вбудовані індивідуальні ітератори

Page 25: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 25

Підхід STL

• Спеціалізовані ітератори, вбудовані в конкретні класи контейнерів

Page 26: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 26

Ітератор, вбудований до масиву

• class Array• {• public:• explicit Array (size_t);• ~Array();• Elem& operator[] (size_t index);• const Elem& operator[] (size_t index) const;• size_t size() const;

• class Iterator;• };

Page 27: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 27

Агрегування масиву ітератором

• class Array::Iterator: public Itor• {• private:• Array * _toIterate;• mutable size_t _current;• public:• Iterator(Array& ar): _toIterate(&ar){};• virtual void begin () const;• virtual const Elem& get() const;• virtual bool done() const;• virtual void next() const;• virtual void put(const Elem &);

Page 28: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 28

Ітератор, вбудований до списку

• class List• {• private: // Закриваємо реалізацію списку• struct Node• {• Elem _elem; Node * _next; Node * _prev;• };• Node * _start;• int _amount;• public:• class Iterator;

Page 29: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 29

Агрегування списку ітератором

• class List::Iterator: public Itor• {• private:• List & _toIterate;• mutable Node * _current;• public:• Iterator(List& lst): _toIterate(lst),_current(0){};• virtual void begin () const;• virtual const Elem& get() const;• virtual bool done() const;• virtual void next() const;• virtual void put(const Elem &);

Page 30: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 30

Сценарій спільного вживання

• // Створення списку і встановлення ітератора• List lst; lst.add('a').add('b').add('c').add('d');• List::Iterator ilst(lst);• // Створення масиву і встановлення ітератора• IteratedArray ar(5);• ar[0]='z'; ar[1]='y'; ar[2]='x'; ar[3]='w'; ar[4]='v';• Array::Iterator iar(ar);

• // Обробка спільною функцією process (Itor &)• process (ilst);• process (iar);

Page 31: 11 Iterated Containers

3. Копіювальні ітератори

Page 32: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 32

Сортування масиву

• void sort(Array & ar)• {• for (size_t i=0; i<ar.size(); ++i)• {• size_t j=i;• for (size_t k=i+1; k<ar.size(); ++k)• if (ar[j]>ar[k]) j=k; // проблемно!!!• Elem x = ar[i]; ar[i] = ar [j]; ar[j] = x;• }• return;• }

Page 33: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 33

Ослаблене сортування масиву

• void sort(Array & ar)• {• for (size_t i=0; i<ar.size(); ++i)• {• size_t j=i;• for (size_t k=i+1; k<ar.size(); ++k)• if (ar[j]>ar[k]) • {Elem x = ar[i]; ar[i] = ar [j]; ar[j] = x;}• }• return;• }

Page 34: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 34

Ітератор масиву з копіювальним конструктором

• class Array::CopyIteratedArray• {• private:• Array * _par;• mutable size_t _current;• public:• explicit CopyIteratedArray(Array& );

CopyIteratedArray(const CopyIteratedArray& );• void begin() const { _current = 0;}• void next() const { ++_current;}• bool done() const { return _current == _par->size();}

Page 35: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 35

Сортування масиву за копіювальним ітератором

• void it_sort(Array & ar)• {• Array::CopyIteratedArray it(ar);• for(it.begin(); !it.done(); it.next())• {• Array::CopyIteratedArray jt(it);• Array::CopyIteratedArray kt(it);• for (kt.next(); !kt.done(); kt.next())• if(jt.get()<kt.get())• {Elem tmp = jt.get(); jt.put(kt.get()); kt.put(tmp);}• }• return;• }

Page 36: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 36

Ітератор списку з копіювальним конструктором

• class List :: CopyIteratedList• {• private:• List & _lst;• mutable Node * _current;• public:• explicit CopyIteratedList (List&);• CopyIteratedList (const CopyIteratedList&);• void begin() const { _current = _lst._start;}• void next() const { _current = _current -> _next;}• bool done() const { return _current == 0;}

Page 37: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 37

Сортування списку за копіювальним ітератором

• void it_sort(List & lst)• {• List::CopyIteratedList it(lst);• for(it.begin(); !it.done(); it.next())• {• List::CopyIteratedList jt(it);• List::CopyIteratedList kt(it);• for (kt.next(); !kt.done(); kt.next())• if(jt.get()<kt.get())• {Elem tmp = jt.get(); jt.put(kt.get()); kt.put(tmp);}• }• return;• }

Page 38: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 38

Діаграма індивідуальних копіювальних ітераторів

Page 39: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 39

Питання

• Як об'єднати інтерфейси• void it_sort(List & lst)• void it_sort(Array & ar)?

• Якби абстрактні класи мали конструктори, то ми б визначили абстрактний клас Itor з копіювальним конструктором

•Wag the dog!

Page 40: 11 Iterated Containers

4. Віртуальні конструкторив абстрактних ітераторах

Page 41: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 41

Абстрактний ітератор з віртуальним конструктором

• class CloneItor• {• public:• virtual ~CloneItor(){ };• virtual CloneItor* clone () const=0;• virtual void begin () const = 0;• virtual const Elem& get () const =0;• virtual void put (const Elem &) = 0;• virtual bool done () const = 0;• virtual void next () const = 0;• };

Page 42: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 42

Ітерований масив

• class Array :: CIteratedArray: public CloneItor• {• private:• Array & _ar;• mutable size_t _current;• public:• explicit CIteratedArray (Array& );• CIteratedArray (const CIteratedArray&);• CIteratedArray* clone() const;• void begin() const ;• void next() const;

Page 43: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 43

• class List :: CIteratedList: public CloneItor• {• private:• List & _lst;• mutable Node * _current;• public:• explicit CIteratedList (List&);• CIteratedList (const CIteratedList&);• CIteratedList* clone() const;• void begin() const ;• void next() const;

Page 44: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 44

Неповна відповідність сигнатур

Сигнатура абстрактного класу• virtual CloneItor* CloneItor :: clone() const;

Сигнатури і реалізації конкретизації• Array::CIteratedArray* Array::CIteratedArray :: clone() const• {• return new CIteratedArray (*this);• }• List::CIteratedList* List :: CIteratedList :: clone() const• {• return new CIteratedList (*this);• }

Page 45: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 45

Застосування

• void sort(CloneItor& it)• {• for (it.begin(); !it.done(); it.next())• {• CloneItor * pjt = it.clone();• CloneItor * pkt = it.clone();• for (pkt->next(); !pkt->done(); pkt->next())• if (pjt->get()>pkt->get())• {Elem tmp = pjt->get(); pjt->put(pkt->get()); pkt->put(tmp);}

delete pjt;• delete pkt;• }• }

Page 46: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 46

Діаграма клонованих ітераторів

Page 47: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 47

Розширений інтерфейс ітератора

• class CloneItor• {• public:• virtual ~CloneItor(){ };• virtual CloneItor* clone() const=0;• virtual Elem& operator*() = 0;• virtual Elem& operator->() = 0;• virtual CloneItor& operator++() = 0;• virtual CloneItor& operator--() = 0;• virtual CloneItor operator++(int) = 0;• virtual CloneItor operator--(int) = 0;

Page 48: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 48

Застосування розширеного ітератора

• void sort(CloneItor& it)• {• for (it.begin(); !it.done(); ++it)• {• CloneItor & jt = * it.clone();• CloneItor & kt = * it.clone();• for (kt->next(); ! kt->done(); ++kt)• if (jt.get()>kt.get())• { Elem tmp = *jt; *jt = *kt; *kt = tmp; }

delete & jt;• delete & kt;• }• }

Page 49: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 49

Проблема

Присвоєння ітераторів

• Чисто віртуальну операцію присвоєння з абстрактного класу

• virtual Itor& Itor::operator=(const Itor&) = 0;

• неможна визначити в похідному класі• virtual IteratedList& List :: IteratedList ::

operator=(const IteratedList &);

Page 50: 11 Iterated Containers

© Бублик В.В. Програмування-2. Ієрархічне програмування. Ітератори в контейнерах 50

Висновки

• Розглянуті індивідуальні ітератори дають доступ до спільного інтерфейсу спеціалізовані контейнери

• Альтернатива універсальні контейнери з об'єднаним інтерфейсом