-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathcar_visitor.cpp
executable file
·129 lines (104 loc) · 3.31 KB
/
car_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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <iostream>
#include <memory>
#include <string>
#include <vector>
/*
* The following example demonstrates the Visitor pattern.
* A tree structure (a car with components like wheels, body, and engine)
* is traversed by different visitors, performing distinct operations.
*/
// Forward declarations
class CarElementVisitor;
class Body;
class Car;
class Engine;
class Wheel;
// Base class for all car elements
class CarElement {
public:
virtual void accept(CarElementVisitor *visitor) = 0; // Pure virtual function
virtual ~CarElement() = default; // Virtual destructor for proper cleanup
};
// Visitor interface
class CarElementVisitor {
public:
virtual void visit(Body *body) = 0;
virtual void visit(Car *car) = 0;
virtual void visit(Engine *engine) = 0;
virtual void visit(Wheel *wheel) = 0;
virtual ~CarElementVisitor() = default;
};
// Concrete element: Wheel
class Wheel : public CarElement {
private:
std::string name;
public:
explicit Wheel(const std::string &name) : name(name) {}
std::string getName() const { return name; }
void accept(CarElementVisitor *visitor) override { visitor->visit(this); }
};
// Concrete element: Body
class Body : public CarElement {
public:
void accept(CarElementVisitor *visitor) override { visitor->visit(this); }
};
// Concrete element: Engine
class Engine : public CarElement {
public:
void accept(CarElementVisitor *visitor) override { visitor->visit(this); }
};
// Concrete element: Car (composite structure)
class Car : public CarElement {
private:
std::vector<std::unique_ptr<CarElement>> elements;
public:
Car() {
elements.emplace_back(std::make_unique<Wheel>("front left"));
elements.emplace_back(std::make_unique<Wheel>("front right"));
elements.emplace_back(std::make_unique<Wheel>("back left"));
elements.emplace_back(std::make_unique<Wheel>("back right"));
elements.emplace_back(std::make_unique<Body>());
elements.emplace_back(std::make_unique<Engine>());
}
void accept(CarElementVisitor *visitor) override {
for (const auto &element : elements) {
element->accept(visitor);
}
visitor->visit(this);
}
};
// Concrete visitor: Performs actions
class CarElementDoVisitor : public CarElementVisitor {
public:
void visit(Body *body) override {
std::cout << "Moving my body" << std::endl;
}
void visit(Car *car) override { std::cout << "Starting my car" << std::endl; }
void visit(Wheel *wheel) override {
std::cout << "Kicking my " << wheel->getName() << " wheel" << std::endl;
}
void visit(Engine *engine) override {
std::cout << "Starting my engine" << std::endl;
}
};
// Concrete visitor: Prints elements
class CarElementPrintVisitor : public CarElementVisitor {
public:
void visit(Body *body) override { std::cout << "Visiting body" << std::endl; }
void visit(Car *car) override { std::cout << "Visiting car" << std::endl; }
void visit(Engine *engine) override {
std::cout << "Visiting engine" << std::endl;
}
void visit(Wheel *wheel) override {
std::cout << "Visiting " << wheel->getName() << " wheel" << std::endl;
}
};
// Main function
int main() {
auto car = std::make_unique<Car>(); // Use smart pointer for safety
CarElementPrintVisitor printVisitor;
CarElementDoVisitor doVisitor;
car->accept(&printVisitor);
car->accept(&doVisitor);
return 0; // No memory leaks
}