To jest stara wersja strony!
Iterator jest uogolniona reprezentacja procesu poruszania sie po kontenerze, niezalezna od typu danych przechowywanych w kontenerze, ale takze od struktury danych samego kontenera.
*p
.p
i q
sa iteratorami, to zdefiniowane jest p = q
.p
i q
sa iteratorami, zdefiniowane sa wyrazenia p == q
oraz p != q
.p
zdefiniowane sa instrukcje p++
oraz ++p
./* klasa wezla kontenera */ template <class Type> struct Node { Type item_; Node* next_; }; template <class Type> class iterator { private: Node<Type>* ptr_; public: iterator(): ptr_(0) {} iterator( Node<Type>* n ): ptr_(n) {} /* operator wyluskania wartosci, na ktora wskazuje iterator */ Type operator* () { return ptr_->item_; } /* preinkrementacja - ++iter */ /* odwiedza nastepny element w kontenerze */ iterator& operator++() { ptr_ = ptr_->next_; return *this; } /* postinkrementacja - iter++ */ iterator& operator++(int) { iterator tmp = *this; ptr_ = ptr_->next_; return tmp; } /* operator porownania == */ /* zwraca true jesli iteratory wskazuja na ten sam element */ bool operator== ( const iterator& i ) { if ( ptr_ == i.ptr_ ) return true; return false; } /* operator nierownosci != */ bool operator!= ( const iterator& i ) { return !( *this == i ); } /* operator przypisania = */ iterator& operator= ( const iterator& i ) { ptr_ = i.ptr_; return *this; } };
Istnieje kilka typow iteratorow, w zaleznosci od udostepnianych operacji:
++i
oraz i++
++i
oraz i++
-—i
oraz i-—
umozliwiajace poruszanie sie po kontenerze w dwoch kierunkachi + n
, czyli wskazanie na n-ty
element po elemencie, na ktory wskazuje i
n + i
(to samo co i + n
)i - n
, czyli wskazanie na n-ty
element przed elementem, na ktory wskazuje i
i += n
(to samo co i = i + n
) oraz i -= n
( i = i - n
)i[]
, czyli *(i + n)
i - j
, czyli wartosc takiego n, ze i = j + n
i < j
, ktore jest prawdziwe gdy j - i > 0
i > j
, ktore jest prawdziwe gdy j < i
i >= j
(analogicznie i ⇐ j
), ktore jest prawdziwe gdy !(i < j)
Rozne funkcje operujace na kontenerach wymagaja iteratora spelniajacego pewne wlasciwosci, np. prototyp funkcji sort ma postac:
template <class RandomAccessIterator> void sort ( RandomAccessIterator first, RandomAccessIterator last );
- czyli podawane argumenty musza udostepniac operacje i + n, i - n itp.
W bibliotece STL kazda klasa kontenerowa posiada definicje odpowiedniego iteratora klasy. Dla jednej moze byc to wskaznik (ktory rowniez moze byc iteratorem, jako ze posiada wszystkie wymagane wlasciwosci), dla innej moze byc to obiekt. Ponadto klasy te posiadaja metody begin() oraz end(), ktore zwracaja iteratory na pierwszy element kontenera oraz na pozycje za ostatnim elementem.
T*
(wskaznik)vector<T>::iterator
vector<T>::const_iterator
deque<T>::iterator
deque<T>::const_iterator
list<T>::iterator
hash_set<T>::iterator
/* Przyklad - korzystanie z iteratorow */ #include <vector> #include <list> #include <iostream> #include <algorithm> int main () { using namespace std; vector<int> v; v.push_back ( 3 ); v.push_back ( 2 ); v.push_back ( 7 ); v.push_back ( 5 ); list<int> l; l.push_back ( 3 ); l.push_back ( 2 ); l.push_back ( 7 ); l.push_back ( 5 ); /* przegladanie kontenera vector za pomoca iteratora */ vector<int>::iterator vi; cout << "vector: "; for ( vi = v.begin(); vi != v.end(); ++vi ){ cout << *vi; } cout << endl; /* przegladanie kontenera list za pomoca iteratora */ /* identycznie jak w przypadku przegladania vectora, choc implementacja kontenerow jest inna */ list<int>::iterator li; cout << "list: "; for ( li = l.begin(); li != l.end(); ++li ){ cout << *li; } cout << endl; /* iterator klasy vector jest typu RandomAccessIterator, mozna wiec uzyc ich do funkcji sort */ sort ( v.begin(), v.end() ); cout << "sorted vector: "; for ( vi = v.begin(); vi != v.end(); ++vi ){ cout << *vi; } cout << endl; /* iterator klasy list jest typu dwukierunkowego, a wiec instrukcja: */ // sort ( l.begin(), l.end() ); /* wywola blad kompilacji z komunikatem, ze list<T>::iteator nie udostepnia operacji - */ return 0; }