
#include <vector>
#include <iostream>
using namespace std;
class Engine;
class Wheel;
class Car;
//Visitor
class CarVisitor {
public:
virtual void visit(Engine* engine) = 0;
virtual void visit(Wheel* wheel) = 0;
virtual void visit(Car* car) = 0;
};
class Element {
public:
virtual void accept(CarVisitor* v) = 0;
};
//ConcreteElement
class Engine: public Element {
public:
void accept(CarVisitor* v) {
v->visit(this);
}
};
//ConcreteElement
class Wheel: public Element {
private:
int number;
public:
Wheel(int number) {
this->number = number;
}
int getNumber() {
return number;
}
void accept(CarVisitor* v) {
v->visit(this);
}
};
//ConcreteElement
class Car: public Element {
private:
vector<Element*> items = {
new Engine(),
new Wheel(1), new Wheel(2),
new Wheel(3), new Wheel(4)};
public:
void accept(CarVisitor* v) {
for (Element* e : items) {
e->accept(v);
}
v->visit(this);
}
};
//ConcreteVisitor
class TestCarVisitor: public CarVisitor {
public:
void visit(Engine* engine) {
cout << "test engine\n";
}
void visit(Wheel* wheel) {
cout << "test wheel #" <<
wheel->getNumber() << "\n";
}
void visit(Car* car) {
cout << "test car\n";
}
};
//ConcreteVisitor
class RepairCarVisitor: public CarVisitor {
public:
void visit(Engine* engine) {
cout << "repair engine\n";
}
void visit(Wheel* wheel) {
cout << "repair wheel #" <<
wheel->getNumber() << "\n";
}
void visit(Car* car) {
cout << "repair car\n";
}
};
//Client
Car car;
CarVisitor* v1 = new TestCarVisitor();
CarVisitor* v2 = new RepairCarVisitor();
car.accept(v1);
car.accept(v2);