Een iterator in C++ is een aanwijzerachtig object dat naar een element van de STL-container verwijst. Ze worden over het algemeen gebruikt om de inhoud van de STL-container in C++ te doorlopen. Het belangrijkste voordeel van STL-iteratoren is dat ze de STL-algoritmen onafhankelijk maken van het gebruikte type container. We kunnen de iterator gewoon doorgeven aan de containerelementen in plaats van de container zelf aan de STL-algoritmen.
Iterator-verklaring
Elke container in C++ STL heeft zijn eigen iterator. We moeten dus een iterator declareren als:
C++
<type>::iterator it;
waar
- type: Type container waarvoor de iterator is gedeclareerd.
- Het: Naam toegewezen aan iteratorobject.
We kunnen het vervolgens initialiseren door een geldige iterator toe te wijzen. Als we al een iterator hebben die moet worden toegewezen op het moment van de delcaratie, kunnen we de typedeclaratie overslaan met behulp van de auto trefwoord.
C++auto it = iter
waar iter is de iterator die is toegewezen aan de nieuw gemaakte it-iterator.
Ons C++ cursus omvat het gebruik van iterators in de STL, zodat u begrijpt hoe u verschillende containertypen moet doorlopen.
Voorbeeld van iteratoren
Het onderstaande programma illustreert hoe u de iterator gebruikt om de vectorcontainer te doorlopen:
C++#include using namespace std; int main() { vector<int> v = {1 2 3 4 5}; // Defining an iterator pointing to // the beginning of the vector vector<int>::iterator first = v.begin(); // Defining an iterator pointing // to the end of the vector vector<int>::iterator last = v.end(); // Iterating the whole vector while(first != last) { cout << *first << ' '; first++; } return 0; }
Uitvoer
1 2 3 4 5
Zoals je misschien gemerkt hebt, hebben we gebruik gemaakt van vector::begin() en vector::end() functie. Deze functies zijn de lidfuncties van std::vector die de iterator retourneren naar het eerste en één element na het laatste element van de vector. We gebruiken de iteratoren die deze functies retourneren om de vectoren te itereren.
Container Iterator-functies
C++ STL biedt enkele lidfuncties in STL-container die de iteratoren retourneren naar ten minste het eerste en het laatste element. Deze lidfuncties zijn gedefinieerd in bijna de hele STL-container (waarbij enkele containers met beperkte toegang overblijven, zoals stapel wachtrij ) met dezelfde naam voor consistentie.
In de volgende tabel worden alle methoden vermeld die de iterator naar de containers retourneren:
Iterator-functie | Retourwaarde |
|---|---|
beginnen() | Retourneert een iterator naar het begin van de container. |
einde() | Retourneert een iterator naar het theoretische element net na het laatste element van de container. |
cbegin() | Retourneert een constante iterator naar het begin van de container. Een constante iterator kan de waarde van het element waarnaar het verwijst niet wijzigen. |
een paar() c++ prototypefunctie | Retourneert een constante iterator naar het theoretische element net na het laatste element van de container. |
rbegin() | Retourneert een omgekeerde iterator naar het begin van de container. |
veroorzaken() | Retourneert een omgekeerde iterator naar het theoretische element net na het laatste element van de container. |
crbegin() | Retourneert een constante omgekeerde iterator naar het begin van de container. |
CREND () | Retourneert een constante omgekeerde iterator naar het theoretische element net na het laatste element van de container. |
Bijvoorbeeld als een ding is de naam van de vector, dan kunnen we de bovenstaande methoden gebruiken, zoals hieronder weergegeven:
C++vec.begin() vec.rbegin() vec.cbegin() vec.crbegin() vec.end() vec.rend() vec.cend() vec.crend()
Iterator-operaties
Net als bij aanwijzerberekeningen zijn er enkele bewerkingen toegestaan op C++-iterators. Ze worden gebruikt om verschillende functionaliteiten te bieden die het belang van iteratoren vergroten. Er zijn er 5 geldig iteratorbewerkingen in C++ :
- Dereferentie van iterators
- Iteratoren verhogen/verlagen
- Geheel getal optellen/aftrekken van iteratoren
- Een andere iterator aftrekken
- Iteratoren vergelijken
Dereferentie van iterators
Door het verwijderen van verwijzingen kunnen de gebruikers dat doen openen of bijwerken de waarde van het element waarnaar de iterator verwijst. Wij gebruiken de (*) indirecte operator om iterators te derefereren, net als pointers.
C++// Access *it; // Update *it = new_val;
waar nieuwe_val is de nieuwe waarde die is toegewezen aan het element waarnaar door de iterator wordt verwezen Het .
Iteratoren verhogen/verlagen
We kunnen de iterator met 1 verhogen of verlagen met behulp van (++) of (--) operatoren respectievelijk. De ophoogbewerking verplaatst de iterator naar het volgende element in de container, terwijl de afbouwbewerking de iterator naar het vorige element verplaatst.
C++it++; // post-increment ++it; // pre-increment it--; // post-decrement --it; // pre-decrement
Geheel getal optellen/aftrekken van iteratoren
We kunnen ook een geheel getalwaarde optellen of aftrekken van de iteratoren. Het zal meer de volgende of vorige positie van de iterator zijn, afhankelijk van de toegevoegde gehele waarde.
C++// Addition it + int_val; // Subtraction it - int_val;
waar int_val zijn de gehele waarden die worden opgeteld of afgetrokken van de iterator Het .
Een andere iterator aftrekken
We kunnen de ene iterator van de andere aftrekken om de afstand (of het aantal elementen) te vinden tussen het geheugen waarnaar ze verwijzen.
C++it1 - it2
Iteratoren vergelijken
We kunnen ook de twee iterators van hetzelfde type tegen elkaar testen om de relatie daartussen te vinden. We kunnen de relationele operatoren zoals (==) gelijkheids- en (!=) ongelijkheidsoperatoren gebruiken, samen met andere relationele operatoren zoals< > <= >=.
C++it1 != it2 // Equal to it1 == it2 // Not equal to it1 > it2 // Greater than it1 < it2 // Less than it1 >= it2 // Greater than equal to it1 <= it2 // Less than equal to
Soorten iteratoren in C++
STL-iteratoren kunnen worden onderverdeeld op basis van de bewerkingen die erop kunnen worden uitgevoerd. Er zijn 5 hoofdtypen iterators in C++, zoals vermeld in de onderstaande tabel, samen met ondersteunde containers en ondersteunde iteratorbewerkingen.
Iterator | Beschrijving | Ondersteunde containers | Ondersteunde operaties |
|---|---|---|---|
Invoeriterator | Het is een eenrichtings-iterator die wordt gebruikt om de waarden te lezen. | Invoerstroom | Dereferentie van toenemende gelijkheid |
Uitvoeriterator | Het is ook een eenrichtings-iterator, maar wordt gebruikt om de waarden toe te wijzen. Het heeft geen toegang tot de waarden. | Uitvoerstroom | Dereferentie verwijderen (alleen schrijven) Verhogen |
Voorwaartse iteratoren | Het heeft toegang tot de waarden en kan deze ook toewijzen. Het is de combinatie van zowel invoer- als uitvoeriterator. | forward_list ongeordende_kaart ongeordende_set | Dereferentie van toenemende gelijkheid |
Bidirectionele iteratoren | Het kan in beide richtingen bewegen, zowel voorwaarts als achterwaarts. De containers zoals lijstset en multimap ondersteunen bidirectionele iterators. | lijst kaartset multimap multiset | Dereferentie van gelijkheid verhogen/verlagen |
Random Access-iteratoren | Iterators met willekeurige toegang zijn iterators die kunnen worden gebruikt om toegang te krijgen tot elementen op afstand van het element waarnaar ze verwijzen, en bieden dezelfde functionaliteit als pointers. | vector deque array-reeks Java-erfenis | Alle |
Zoals we misschien hebben opgemerkt in de bovenstaande tabel, afgezien van de invoer- en uitvoeriteratoren Naarmate we verder in de tabel komen, bevat het iteratortype de functies van de bovenstaande iterator, samen met enkele nieuwe functies.
Iterator-adapters
Iteratoradapters in C++ zijn het speciale type iterators die over traditionele iterators heen zijn gebouwd om gespecialiseerde functionaliteit te bieden. Er zijn veel iteratoradapters in C++, waarvan er enkele hieronder worden gegeven:
Type iteratoradapters | Beschrijving |
|---|---|
Omgekeerde iterator | De omgekeerde iterator is gebouwd over een bidirectioneel of hoger type operator en stelt gebruikers in staat de container in de omgekeerde richting te doorkruisen. |
Stream-iterators | De stream-iteratoren, namelijk istream- en ostream-iteratoren, zijn respectievelijk gebouwd op de invoer- en uitvoer-iteratoren. Met deze iterators kunnen gebruikers de streams als containers gebruiken. |
Verplaats iteratoren | Verplaatsiteratoren worden gebruikt om de verplaatsingssemantiek in STL-algoritmen te introduceren. De verplaatsingiterators verplaatsen het eigendom van de gekopieerde containergegevens naar de kopieercontainer zonder de extra kopieën te maken. |
Inserter-iterator | Met de insertor-iteratoren kunt u de gegeven elementen op een bepaalde positie in de container invoegen. Er zijn drie insertor-iterators in C++:
Deze iterators kunnen worden gemaakt met behulp van back_inserter() front_inserter() invoegen() functies in C++. |
Iterator-hulpprogrammafuncties in C++
C++ STL biedt verschillende functies om het werken met iteratoren te vereenvoudigen. Ze staan vermeld in de onderstaande tabel:
| Functie | Beschrijving | Syntaxis |
|---|---|---|
| standaard::vooruitgang | Zet een iterator een bepaald aantal posities vooruit. | voorschot ( het n ) |
| std::volgende | Retourneert de iterator die een opgegeven aantal posities vóór ligt op de gegeven iterator. | volgende ( het n ) |
| Std :: Vorige | Retourneert de iterator die een opgegeven aantal posities achter de gegeven iterator ligt. | vorige ( het n ) |
| standaard::afstand | Retourneert het aantal elementen tussen twee iterators. | afstand ( het1 het2 ) |
| std::begin | Retourneert een iterator naar het eerste element van de gegeven container. | beginnen ( houder ) |
| std::einde | Retourneert een iterator naar het element dat volgt op het laatste element van de gegeven container. | einde ( houder ) |
| std::rbegin | Retourneert een omgekeerde iterator naar het laatste element van de gegeven container. | rbegin ( houder ) |
| std::rend | Retourneert een omgekeerde iterator naar het element dat voorafgaat aan het eerste element van de gegeven container. | maakt ( houder ) |
| std::invoeger | Creëert een invoeg-iterator die elementen op een opgegeven positie in een container invoegt. | invoeger ( containerpositie ) |
| std::back_inserter | Creëert een back-insert-iterator die elementen aan het einde van een container toevoegt. | back_inserter ( houder ) |
| std::front_inserter | Creëert een front insert iterator die elementen aan de voorkant van een container invoegt. | front_inserter ( houder ) |
Toepassingen van iterators met voorbeelden
Iterators worden veelvuldig gebruikt in C++ voor veel verschillende doeleinden tijdens het werken met STL-containers en algoritmen. Hieronder volgen enkele primaire toepassingen van iterators in C++ met hun codevoorbeelden:
Containers doorkruisen
Het doorkruisen van STL-containers is de meest basale toepassing van iterators. Hierin gebruiken we de functies begin() en end() om de begin- en einditeratoren de hele container te laten doorlopen. In principe blijven we de begin-iterator verhogen totdat deze niet gelijk is aan het einde.
Voorbeeld
C++#include using namespace std; int main() { set<int> s = {10 20 30 40 50}; // Iterator to the beginning // of the set auto it = s.begin(); // Iterating through the // entire set while (it != s.end()) { // Dereferencing iterator // to access value cout << *it << ' '; // Incrementing the // iterator it++; } return 0; }
Uitvoer
10 20 30 40 50
Zoals weergegeven in de bovenstaande code doorkruisen we de ingestelde container. Op dezelfde manier kunnen we dezelfde aanpak gebruiken om elke container te doorkruisen.
Het omkeren van een container
Met omgekeerde iterators kunt u een container van het einde naar het begin doorlopen zonder dat u de omkering handmatig hoeft af te handelen.
Voorbeeld
C++#include using namespace std; int main() { vector<int> vec = {10 20 30 40 50}; // Defining reverse iterators // pointing to the reverse // beginning of vec auto it = vec.rbegin(); // Iterating the whole // vector in reverse while (it != vec.rend()) { cout << *it << ' '; it++; } return 0; }
Uitvoer
50 40 30 20 10
Container-onafhankelijke algoritmen
Met iterators kunnen algoritmen met elk containertype werken, waardoor functies als std::sort() std::find() en std::for_each() flexibeler worden. U kunt iterators doorgeven in plaats van de daadwerkelijke container.
Voorbeeld
C++#include using namespace std; int main() { vector<int> vec = {30 10 40 10 50}; multiset<int> ms = {10 30 10 20 40 10}; // Using the std::count() algorithm to count // the number of occurences of 10 in vector // and multiset using iterator cout << '10s in Vector: ' << count(vec.begin() vec.end() 10) << endl; cout << '10s in Multiset: ' << count(ms.begin() ms.end() 10); return 0; }
Uitvoer
10s in Vector: 2 10s in Multiset: 3
Aanvullende toepassingen van iteratoren
Er zijn meer toepassingen van STL-iteratoren:
- Afstandsberekening: Met behulp van std::distance() iterators kunt u het aantal elementen tussen twee posities in een container berekenen.
- Stream-iteratie: Met streamiterators kunt u invoer-/uitvoerstreams behandelen als containers, waardoor het gemakkelijker wordt om streams te lezen en ernaar te schrijven met behulp van STL-algoritmen.
- Verplaats semantiek in STL-algoritmen: Verplaatsiterators introduceren de verplaatsingssemantiek in STL-algoritmen, wat helpt bij het verbeteren van de prestaties en efficiëntie door onnodig kopiëren te voorkomen. De gegevens worden verplaatst volgens de regels van de verplaatsingssemantiek.
- Aangepaste iterators voor gegevensstructuren: Aangepaste iterators kunnen worden geïmplementeerd voor niet-STL-gegevensstructuren zoals bomen of grafieken om ondersteuning te bieden voor STL-algoritmen en vele andere functies. Mogelijk moeten we een aantal regels en conventies volgen om de juiste oplopende, aflopende en andere bewerkingen te kunnen uitvoeren.