STL Iteratoren
← STL Beispiele | ● | STL Iterator Beispiel →
Iteratoren sind ein generalisiertes “Design-Pattern” bzw. Programmierschema, mit dem die Elemente einer beliebigen Containerklasse aufgezählt werden können.
Ein Iterator ist ein generalisierter Zeiger. Mit Iteratoren ist der Zugriff auf die Elemente einer Containerklasse<T> möglich, wobei die üblichen Zeigeroperatoren *, == und ++ überladen sind und folgende Bedeutung haben:
- * dereferenziert den Zeiger und liefert ein Element vom Datentyp T.
- == vergleicht zwei Zeiger auf jeweils ein Element vom Datentyp T.
- ++ inkrementiert den Zeiger und liefert den Zeiger auf das nächste Element der Datenstruktur.
Eine Aufzählung aller Elemente einer beliebigen Containerklasse mit Elementen vom templatisierten Typ T ist damit mit einer for-Schleife nach folgendem Muster möglich:
for (Container<T>::iterator i = v.begin(); i != v.end(); i++) // overloaded comparison and increment operator
std::cout << (*i); // overloaded dereference operator for element access
Iteratoren sind kurzfristig erzeugte Zeiger-Objekte, die für einen kompletten Schleifendurchlauf existieren, der für eine bestimmte Containerklasse erfolgen soll. Die Containerklasse erzeugt dabei das erste Iterator-Objekt mit der Methode begin() selbst. Die Methode begin() liefert also einen Zeiger auf das erste Objekt. Das Ende der Schleife ist erreicht, wenn der Iterator identisch zum Rückgabewert der Methode end() ist.
Man sagt dann, dass der Iterator über alle Elemente dieses Containers iteriert.
Beispiel für die std::vector<int> Klasse der STL (Standard Template Library):
for (std::vector<int>::iterator i = v.begin(); i != v.end(); i++)
std::cout << (*i) << ", ";
Ergibt als Ausgabe: “1, 2, 3 “
Im C++ Sprachstandard C++0x gibt es eine elegantere Schreibweise mit auto Variablen, welche automatisch den Datentyp des ihr zugewiesenen Ausdruckes annehmen:
for (auto i = v.begin(); i != v.end(); i++)
std::cout << (*i) << ", ";
In C++11 gibt es eine noch elegantere Schreibweise mit einer for-Schleifenvariante, die sinngemäß eine “foreach”-Schleife darstellt:
std::cout << i << ", ";
In diesem Fall ist i jedoch kein Zeiger, sondern bereits eine Kopie eines Elementes. Um unnötige Kopien zu vermeiden, verwendet man lieber Element-Referenzen:
std::cout << i << ", ";
Vorteile:
- Durch Compileroptimierung keine Performanzeinbußen gegenüber althergebrachter for-Schleife.
- Selbe Schleifen-Syntax für alle Containerklassen, egal ob indizierbare Arrays, nicht-indizierbare Bäume, Graphen oder Key-Value Pairs etc. pp. → Generalisierung
← STL Beispiele | ● | STL Iterator Beispiel →