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

http://patterns.pl/png/iteratorclass.png
http://patterns.pl/png/iteratorseq.png

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;
}

Leave a Reply

Your email address will not be published. Required fields are marked *