-
Notifications
You must be signed in to change notification settings - Fork 5
/
visitor.cpp
102 lines (86 loc) · 2.44 KB
/
visitor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Visitor design pattern
#include <functional>
#include <iostream>
#include <memory>
#include <vector>
// object hierarchy we will visit
class IObject {
public:
virtual void accept(class IVisitor& visitor) = 0;
virtual ~IObject() = default;
};
class Car : public IObject {
public:
std::string car() const { return "Car"; }
void accept(IVisitor& visitor) override;
};
class Plane : public IObject {
public:
std::string plane() const { return "Plane"; }
void accept(IVisitor& visitor) override;
};
class Train : public IObject {
public:
std::string train() const { return "Train"; }
void accept(IVisitor& visitor) override;
};
// visitor hierarchy
class IVisitor {
public:
virtual void visit(Car& car) = 0;
virtual void visit(Plane& plane) = 0;
virtual void visit(Train& plane) = 0;
virtual ~IVisitor() = default;
};
// accept the visitor(s)
void Car::accept(IVisitor& visitor) {
visitor.visit(*this); // double dispatching
}
void Plane::accept(IVisitor& visitor) { visitor.visit(*this); }
void Train::accept(IVisitor& visitor) { visitor.visit(*this); }
// define as many visitors as you want
// first type of visitor, implement some functionality
class VisitorOne : public IVisitor {
void visit(Car& car) override {
std::cout << "Visitor one on " << car.car() << '\n';
}
void visit(Plane& plane) override {
std::cout << "Visitor one on " << plane.plane() << '\n';
}
void visit(Train& train) override {
std::cout << "Visitor one on " << train.train() << '\n';
}
};
// second type of visitor, different functionality
class VisitorTwo : public IVisitor {
void visit(Car& car) override {
std::cout << "Visitor two on " << car.car() << '\n';
}
void visit(Plane& plane) override {
std::cout << "Visitor two on " << plane.plane() << '\n';
}
void visit(Train& train) override {
std::cout << "Visitor two on " << train.train() << '\n';
}
};
int main() {
// objects
Car car;
Plane plane;
Train train;
std::vector<std::reference_wrapper<IObject>> objects;
objects.emplace_back(car);
objects.emplace_back(plane);
objects.emplace_back(train);
// visitors
VisitorOne vis_one;
VisitorTwo vis_two;
// first visitor
for (auto&& elem : objects) {
elem.get().accept(vis_one);
}
// second visitor
for (auto&& elem : objects) {
elem.get().accept(vis_two);
}
}