Iteratoren
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 72 von 104.
Iteratoren sind Objekte, die als Brücke zwischen Containern und Algorithmen dienen. Sie bieten eine einheitliche Möglichkeit, auf Elemente in jedem Container zuzugreifen, unabhängig davon, wie dieser Container seine Daten intern speichert. Stell dir einen Iterator als einen verallgemeinerten Zeiger vor, der weiß, wie er sich durch einen Container bewegt.
Jeder STL-Container stellt die Methoden begin() und end() bereit. Der Iterator begin() zeigt auf das erste Element, während end() auf die Position direkt hinter dem letzten Element zeigt – ein Sentinel, der markiert, wo angehalten werden soll:
#include <vector>
#include <iostream>
int main() {
std::vector<int> nums = {10, 20, 30};
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << " "; // Dereferenzieren, um den Wert zu erhalten
}
// Ausgabe: 10 20 30
}Das Schlüsselwort auto vereinfacht Deklarationen von Iteratoren erheblich:
for (auto it = nums.begin(); it != nums.end(); ++it) {
*it *= 2; // Elemente über Iterator modifizieren
}
// nums ist jetzt {20, 40, 60}Iteratoren gibt es je nach ihren Fähigkeiten in verschiedenen Kategorien. Iteratoren mit wahlfreiem Zugriff (wie die aus vector) unterstützen arithmetische Operationen wie it + 3 oder it1 - it2.
Bidirektionale Iteratoren (aus list, map) können sich mit ++ und -- vorwärts und rückwärts bewegen. Vorwärts-Iteratoren können sich nur in eine Richtung bewegen.
Für die Rückwärtsdurchlaufung verwende rbegin() und rend():
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
std::cout << *rit << " "; // Gibt in umgekehrter Reihenfolge aus
}Aufgabe
EinfachErstellen wir ein Bestandsverfolgungssystem, das Iteratoren verwendet, um Sammlungen von Artikeln zu durchlaufen und zu bearbeiten. Du übst, verschiedene Iteratortypen zu verwenden, um Daten auf unterschiedliche Weise zu durchlaufen.
Du organisierst deinen Code auf zwei Dateien:
Inventory.h: Definiere eineInventory-Klasse, die eine Sammlung von Artikelmengen verwaltet, die in einemstd::vector<int>gespeichert sind.Deine Klasse sollte diese Methoden bereitstellen:
addItem(int quantity): fügt dem Bestand eine Artikelmenge hinzuprintForward(): verwendet Iteratoren mitbegin()undend(), um alle Mengen durch Leerzeichen getrennt auszugeben, gefolgt von einem ZeilenumbruchprintReverse(): verwendet umgekehrte Iteratoren mitrbegin()undrend(), um alle Mengen in umgekehrter Reihenfolge durch Leerzeichen getrennt auszugeben, gefolgt von einem ZeilenumbruchdoubleAll(): verwendet Iteratoren, um den Vektor zu durchlaufen und jede Menge direkt zu verdoppelngetTotal(): verwendet Iteratoren, um die Summe aller Mengen zu berechnen und zurückzugeben
Verwende das Schlüsselwort
autofür deine Iterator-Deklarationen, damit der Code übersichtlich bleibt.main.cpp: Lies vier ganzzahlige Eingaben ein, jeweils eine pro Zeile, die Artikelmengen darstellen.Erstelle ein
Inventory-Objekt und füge alle vier Mengen hinzu. Demonstriere anschließend die Verwendung von Iteratoren, indem du:Forward:ausgibst und danachprintForward()aufrufstReverse:ausgibst und danachprintReverse()aufrufstTotal: <sum>mithilfe vongetTotal()ausgibstdoubleAll()aufrufst, um die Mengen zu ändernAfter doubling:ausgibst und danachprintForward()aufrufstNew total: <sum>mithilfe vongetTotal()ausgibst
Beispiel: Bei den Eingaben 10, 25, 15 und 30:
Forward: 10 25 15 30
Reverse: 30 15 25 10
Total: 80
After doubling: 20 50 30 60
New total: 160Mit dieser Aufgabe kannst du sowohl das Lesen von Elementen mithilfe von Iteratoren (zum Ausgeben und Addieren) als auch das Ändern von Elementen mithilfe von Iteratoren (zum Verdoppeln) üben. Außerdem siehst du, wie umgekehrte Iteratoren das Durchlaufen in umgekehrter Richtung ohne jegliche Indexbearbeitung vereinfachen.
Probier es selbst
#include <iostream>
#include "Inventory.h"
using namespace std;
int main() {
// Lies vier Ganzzahl-Eingaben
int q1, q2, q3, q4;
cin >> q1;
cin >> q2;
cin >> q3;
cin >> q4;
// TODO: Erstelle ein Inventory-Objekt
// TODO: Füge alle vier Mengen zum Inventar hinzu
// TODO: Gib "Forward: " aus und rufe dann printForward() auf
// TODO: Gib "Reverse: " aus und rufe dann printReverse() auf
// TODO: Gib "Total: " gefolgt vom Ergebnis von getTotal() aus
// TODO: Rufe doubleAll() auf, um die Mengen zu ändern
// TODO: Print "After doubling: " then call printForward()
// TODO: Gib "New total: " gefolgt vom Ergebnis von getTotal() aus
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler