Narzędzia użytkownika

Narzędzia witryny


iterator

To jest stara wersja strony!


Iterator

Iterator jest uogolniona reprezentacja procesu poruszania sie po kontenerze, niezalezna od typu danych przechowywanych w kontenerze, ale takze od struktury danych samego kontenera.

Cechy iteratora:

  1. Mozliwosc wyluskania iteratora w celu uzyskania dostepu do wartosci, na ktora wskazuje. Jesli p jest iteratorem, to jest zdefiniowane wyrazenie *p.
  2. Mozliwosc przypisania jednego iteratora do drugiego. Jesli p i q sa iteratorami, to zdefiniowane jest p = q.
  3. Mozliwosc porownania jednego iteratora z drugim. Jesli p i q sa iteratorami, zdefiniowane sa wyrazenia p == q oraz p != q.
  4. Za pomoca iteratora mozna odwiedzic wszystkie elementy kontenera. Dla iteratora p zdefiniowane sa instrukcje p++ oraz ++p.

Przykladowy iterator

/* 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;
	}
};

Rodzaje iteratorow

Istnieje kilka typow iteratorow, w zaleznosci od udostepnianych operacji:

iterator wejsciowy
  • wyluskiwanie do odczytu
  • operacje ++i oraz i++
iterator wyjsciowy
  • wyluskiwanie do zapisu
  • operacje ++i oraz i++
iterator postepujacy
  • operacje iteratorow wejsciowego oraz wyjsciowego
iterator dwukierunkowy
  • operacje iteratora postepujacego
  • operacje –i oraz i– umozliwiajace poruszanie sie po kontenerze w dwoch kierunkach
iterator dostepu swobodnego (RandomAccessIterator)
  • operacje iteratora dwukierunkowego
  • operacja i + n, czyli wskazanie na n-ty element po elemencie, na ktory wskazuje i
  • operacja n + i (to samo co i + n)
  • operacja 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 )
  • operator 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.

Iteratory w bibliotece standardowej

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.

Iteratory dostepu swobodnego:
  • T* (wskaznik)
  • vector<T>::iterator
  • vector<T>::const_iterator
  • deque<T>::iterator
  • deque<T>::const_iterator
Iteratory dwukierunkowe:
  • list<T>::iterator
Iteratory postepujace:
  • hash_set<T>::iterator

Korzystanie z iteratorow

/* 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;
}
iterator.1229044346.txt.gz · ostatnio zmienione: 2008/12/12 02:12 przez gierek