/* * C++ Design Patterns: Visitor * Author: Jakub Vojvoda [github.com/JakubVojvoda] * 2016 * * Source code is licensed under MIT License * (for more details see LICENSE) * */ #include class Element; class ConcreteElementA; class ConcreteElementB; /* * Visitor * declares a Visit operation for each class of ConcreteElement * in the object structure */ class Visitor { public: virtual void visitElementA(ConcreteElementA *element) = 0; virtual void visitElementB(ConcreteElementB *element) = 0; // ... }; /* * Concrete Visitors * implement each operation declared by Visitor, which implement * a fragment of the algorithm defined for the corresponding class * of object in the structure */ class ConcreteVisitor1 : public Visitor { public: void visitElementA(ConcreteElementA *) { std::cout << "Concrete Visitor 1: Element A visited." << std::endl; } void visitElementB(ConcreteElementB *) { std::cout << "Concrete Visitor 1: Element B visited." << std::endl; } // ... }; class ConcreteVisitor2 : public Visitor { public: void visitElementA(ConcreteElementA *) { std::cout << "Concrete Visitor 2: Element A visited." << std::endl; } void visitElementB(ConcreteElementB *) { std::cout << "Concrete Visitor 2: Element B visited." << std::endl; } // ... }; /* * Element * defines an accept operation that takes a visitor as an argument */ class Element { public: virtual void accept(Visitor &visitor) = 0; // ... }; /* * Concrete Elements * implement an accept operation that takes a visitor as an argument */ class ConcreteElementA : public Element { public: void accept(Visitor &visitor) { visitor.visitElementA(this); } // ... }; class ConcreteElementB : public Element { public: void accept(Visitor &visitor) { visitor.visitElementB(this); } // ... }; int main() { ConcreteElementA elementA; ConcreteElementB elementB; ConcreteVisitor1 visitor1; ConcreteVisitor2 visitor2; elementA.accept(visitor1); elementA.accept(visitor2); elementB.accept(visitor1); elementB.accept(visitor2); return 0; }