Menu
Coddy logo textTech

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 fungieren. Sie bieten eine einheitliche Möglichkeit, auf Elemente in jedem Container zuzugreifen, unabhängig davon, wie dieser Container seine Daten intern speichert. Stellen Sie sich einen Iterator als einen verallgemeinerten Zeiger vor, der weiß, wie man sich durch einen Container bewegt.

Jeder STL-Container bietet begin() und end() Methoden an. Der begin() Iterator zeigt auf das erste Element, während end() auf die Position hinter dem letzten Element zeigt – ein Sentinel, der markiert, wo gestoppt 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 Iterator-Deklarationen erheblich:

for (auto it = nums.begin(); it != nums.end(); ++it) {
    *it *= 2;  // Elemente über Iterator modifizieren
}
// nums ist jetzt {20, 40, 60}

Iteratoren werden basierend auf ihren Fähigkeiten in verschiedene Kategorien unterteilt. Random-Access-Iteratoren (wie die von vector) unterstützen arithmetische Operationen wie it + 3 oder it1 - it2.

Bidirektionale Iteratoren (von 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 das rückwärtsgerichtete Durchlaufen verwenden Sie rbegin() und rend():

for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
    std::cout << *rit << " ";  // Ausgabe in umgekehrter Reihenfolge
}
challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Inventarverfolgungssystem erstellen, das Iteratoren verwendet, um Sammlungen von Elementen zu durchlaufen und zu manipulieren. Sie werden üben, verschiedene Iteratortypen zu verwenden, um auf unterschiedliche Weise durch Daten zu navigieren.

Sie werden Ihren Code auf zwei Dateien verteilen:

  • Inventory.h: Definieren Sie eine Inventory-Klasse, die eine Sammlung von Artikelmengen verwaltet, die in einem std::vector<int> gespeichert sind.

    Ihre Klasse sollte diese Methoden bereitstellen:

    • addItem(int quantity) — fügt dem Inventar eine Artikelmenge hinzu
    • printForward() — verwendet Iteratoren mit begin() und end(), um alle Mengen durch Leerzeichen getrennt auszugeben, gefolgt von einem Zeilenumbruch
    • printReverse() — verwendet Reverse-Iteratoren mit rbegin() und rend(), um alle Mengen in umgekehrter Reihenfolge durch Leerzeichen getrennt auszugeben, gefolgt von einem Zeilenumbruch
    • doubleAll() — verwendet Iteratoren, um den Vektor zu durchlaufen und jede Menge an Ort und Stelle zu verdoppeln
    • getTotal() — verwendet Iteratoren, um die Summe aller Mengen zu berechnen und zurückzugeben

    Verwenden Sie das Schlüsselwort auto für Ihre Iteratordeklarationen, um den Code sauber zu halten.

  • main.cpp: Lesen Sie vier Ganzzahleingaben (jede in einer separaten Zeile) ein, die Artikelmengen darstellen.

    Erstellen Sie ein Inventory-Objekt und fügen Sie alle vier Mengen hinzu. Demonstrieren Sie dann die Verwendung von Iteratoren durch:

    1. Ausgabe von Forward: gefolgt vom Aufruf von printForward()
    2. Ausgabe von Reverse: gefolgt vom Aufruf von printReverse()
    3. Ausgabe von Total: <sum> unter Verwendung von getTotal()
    4. Aufruf von doubleAll(), um die Mengen zu ändern
    5. Ausgabe von After doubling: gefolgt vom Aufruf von printForward()
    6. Ausgabe von New total: <sum> unter Verwendung von getTotal()

Zum Beispiel mit 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: 160

Diese Herausforderung ermöglicht es Ihnen, sowohl das Lesen von Elementen über Iteratoren (zum Drucken und Summieren) als auch das Ändern von Elementen über Iteratoren (zum Verdoppeln) zu üben. Sie werden auch sehen, wie Reverse-Iteratoren das Rückwärtsdurchlaufen ohne Indexmanipulation einfach machen.

Spickzettel

Iteratoren sind Objekte, die eine einheitliche Möglichkeit bieten, auf Elemente in Containern zuzugreifen. Sie fungieren als verallgemeinerte Zeiger, die wissen, wie man sich durch einen Container bewegt.

Jeder STL-Container bietet die Methoden begin() und end() an. Der begin()-Iterator zeigt auf das erste Element, während end() auf die Position hinter dem letzten Element zeigt:

std::vector<int> nums = {10, 20, 30};

for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
    std::cout << *it << " ";  // Dereference to get value
}

Verwenden Sie das Schlüsselwort auto, um Iterator-Deklarationen zu vereinfachen:

for (auto it = nums.begin(); it != nums.end(); ++it) {
    *it *= 2;  // Modify elements through iterator
}

Iterator-Kategorien basierend auf ihren Fähigkeiten:

  • Random access iterators (z. B. vector) unterstützen arithmetische Operationen wie it + 3 oder it1 - it2
  • Bidirectional iterators (z. B. list, map) können sich mit ++ und -- vorwärts und rückwärts bewegen
  • Forward iterators können sich nur in eine Richtung bewegen

Für den rückwärtigen Durchlauf verwenden Sie rbegin() und rend():

for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {
    std::cout << *rit << " ";  // Prints in reverse order
}

Probier es selbst

#include <iostream>
#include "Inventory.h"

using namespace std;

int main() {
    // Lies vier Ganzzahl-Eingaben ein
    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: " aus, gefolgt vom Ergebnis von getTotal()

    // TODO: Rufe doubleAll() auf, um die Mengen zu modifizieren

    // TODO: Gib "After doubling: " aus und rufe dann printForward() auf

    // TODO: Gib "New total: " aus, gefolgt vom Ergebnis von getTotal()

    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung