This section covers the concrete C++ implementation of the Interpreter pattern using Boolean expressions, then introduces the Iterator pattern — a behavioral pattern that provides sequential access to aggregate elements without exposing internal representation.
Interpreter (completion):
VariableExp, AndExp, OrExp, NotExp, Constant form a class hierarchy implementing BooleanExpEvaluate, Replace, Copy — are all forms of "interpretation" distributed over the composite treeReplace is an interpreter whose context is a variable name and substitution expression; its result is a new expression treeIterator:
CreateIterator() factory methodFirst(), Next(), IsDone(), CurrentItem()Interpreter — Boolean expression tree construction and evaluation:
VariableExp* x = new VariableExp("X");
VariableExp* y = new VariableExp("Y");
BooleanExp* expression = new OrExp(
new AndExp(new Constant(true), x),
new AndExp(y, new NotExp(x))
);
Context context;
context.Assign(x, false);
context.Assign(y, true);
bool result = expression->Evaluate(context); // true
// Substitution via Replace
BooleanExp* replacement = expression->Replace("Y", not_z);
Iterator — external iterator usage:
List<Employee*>* employees;
ListIterator<Employee*> forward(employees);
ReverseListIterator<Employee*> backward(employees);
void PrintEmployees(Iterator<Employee*>& i) {
for (i.First(); !i.IsDone(); i.Next()) {
i.CurrentItem()->Print();
}
}
Polymorphic iteration with factory method:
AbstractList<Employee*>* employees;
Iterator<Employee*>* iterator = employees->CreateIterator();
PrintEmployees(*iterator);
delete iterator;
IteratorPtr (RAII proxy for safe cleanup):
IteratorPtr<Employee*> iterator(employees->CreateIterator());
PrintEmployees(*iterator); // auto-deleted when proxy goes out of scope
Internal iterator (ListTraverser with subclassing):
class PrintNEmployees : public ListTraverser<Employee*> {
protected:
bool ProcessItem(Employee* const& e) {
_count++;
e->Print();
return _count < _total; // false stops traversal
}
};
CreateIterator() connects parallel aggregate/iterator hierarchiesIsDone() == true) simplifies traversal of tree structures with leaf nodesfor loop); Internal = iterator controls (applies operation to each element). External is more flexible (can compare two collections); internal is easier to use but weak in C++ without closuresIsDone() always returns true; enables uniform traversal of composites without special-casing leaf nodesTestItem() predicate to skip elements — shows how internal iterators encapsulate iteration policies