Iterator pattern
1. Usage
- Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
- makes possible to decouple collection classes and algorithms.
- Promote to "full object status" the traversal of a collection.
- Polymorphic traversal
2. UML class diagram


3. Pros
- shields the client from the internal representation of aggregator.
- aggregate can be iterated in many different ways.
- more than one iterator can be active - the iterator stores the current state so each is self contained.
4. Cons
- uses AbsractFactory so have to define a ConcreteAggregate in addition to ConcreteIterator
- if the underlying aggregate is updated while using an Iterator, the operation of the Iterator may be undefined.
5. Source code
// http://patterns.pl/iterator.html
#include <iostream>
#include <vector>
#include <memory>
#include <stdexcept>
using namespace std;
template<typename T>
class Iterator
{
public:
virtual void first() = 0;
virtual void next() = 0;
virtual bool isDone() const = 0;
virtual T& current() = 0;
};
template<typename T>
class VectorIterator : public Iterator<T>
{
vector<T> vect;
size_t position;
public:
VectorIterator(vector<T> & v) : vect(v), position(0) {}
void first() override
{
position = 0;
}
void next() override
{
++position;
}
bool isDone() const override
{
return !(position < vect.size());
}
T& current() override
{
if (!isDone())
{
return vect.at(position);
}
throw out_of_range("out of range");
}
};
int main()
{
vector<int> v{ 1, 2, 3 };
VectorIterator<int> vIter(v);
// use interface so you can switch easly in case different implementation
Iterator<int> &iter = vIter;
for (iter.first(); !iter.isDone(); iter.next())
{
cout << iter.current() << endl;
}
return 0;
}