CODESAMPLE

Iterator - C++

Share on:

The Iterator pattern provides a way to access elements of an aggregate object sequentially without exposing its underlying representation. It defines an interface for traversing a collection, allowing clients to request the next element and check if there are more elements, without knowing anything about how the collection is stored. This code showcases a ConcreteAggregate (a vector) and a ConcreteIterator to traverse it. The iterator provides hasNext() and next() methods. This C++ implementation leverages the Standard Template Library (STL) concepts and adheres to RAII principles by implicitly managing iterator lifecycle, characteristic of idiomatic C++ design.

#include <iostream>
#include <vector>

// Forward declaration
class Iterator;

// Aggregate interface
class Aggregate {
public:
    virtual Iterator* createIterator() = 0;
};

// Iterator interface
class Iterator {
public:
    virtual bool hasNext() = 0;
    virtual int next() = 0;
};

// Concrete Aggregate
class ConcreteAggregate : public Aggregate {
private:
    std::vector<int> data;

public:
    void setData(const std::vector<int>& data) { this->data = data; }

    Iterator* createIterator() override;
};

// Concrete Iterator
class ConcreteIterator : public Iterator {
private:
    ConcreteAggregate* aggregate;
    int current_index;

public:
    ConcreteIterator(ConcreteAggregate* aggregate) : aggregate(aggregate), current_index(0) {}

    bool hasNext() override {
        return current_index < aggregate->data.size();
    }

    int next() override {
        if (hasNext()) {
            return aggregate->data[current_index++];
        } else {
            return -1; // Or throw an exception
        }
    }
};

Iterator* ConcreteAggregate::createIterator() {
    return new ConcreteIterator(this);
}

int main() {
    ConcreteAggregate concrete_aggregate;
    std::vector<int> my_data = {1, 2, 3, 4, 5};
    concrete_aggregate.setData(my_data);

    Iterator* iterator = concrete_aggregate.createIterator();

    while (iterator->hasNext()) {
        std::cout << iterator->next() << " ";
    }
    std::cout << std::endl;

    delete iterator; // Important for manual memory management
    return 0;
}