Skip to content

Commit 4cd1459

Browse files
committed
add Visitor pattern
1 parent eb7226c commit 4cd1459

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

visitor/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Visitor
2+
3+
Visitor represents an operation to be performed on the elements of an object
4+
structure. It lets you define a new operation without changing the classes of
5+
the elements on which it operates. The pattern has behavioral purpose and applies
6+
to the objects.
7+
8+
### When to use
9+
10+
* an object structure contains many classes of objects with differing interfaces,
11+
and you want to perform operations on these objects that depend on their concrete classes
12+
* many distinct and unrelated operations need to be performed on objects in an object structure,
13+
and you want to avoid "polluting" their classes with these operations
14+
* the classes defining the object structure rarely change, but you often want
15+
to define new operations over the structure

visitor/Visitor.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* C++ Design Patterns: Visitor
3+
* Author: Jakub Vojvoda [github.com/JakubVojvoda]
4+
* 2016
5+
*
6+
* Source code is licensed under MIT License
7+
* (for more details see LICENSE)
8+
*
9+
*/
10+
11+
#include <iostream>
12+
13+
class Element;
14+
class ConcreteElementA;
15+
class ConcreteElementB;
16+
17+
/*
18+
* Visitor
19+
* declares a Visit operation for each class of ConcreteElement
20+
* in the object structure
21+
*/
22+
class Visitor {
23+
public:
24+
virtual void visitElementA(ConcreteElementA *element) = 0;
25+
virtual void visitElementB(ConcreteElementB *element) = 0;
26+
};
27+
28+
/*
29+
* Concrete Visitors
30+
* implement each operation declared by Visitor, which implement
31+
* a fragment of the algorithm defined for the corresponding class
32+
* of object in the structure
33+
*/
34+
class ConcreteVisitor1 : public Visitor {
35+
public:
36+
void visitElementA(ConcreteElementA *) {
37+
std::cout << "Concrete Visitor 1: Element A visited." << std::endl;
38+
}
39+
40+
void visitElementB(ConcreteElementB *) {
41+
std::cout << "Concrete Visitor 1: Element B visited." << std::endl;
42+
}
43+
};
44+
45+
class ConcreteVisitor2 : public Visitor {
46+
public:
47+
void visitElementA(ConcreteElementA *) {
48+
std::cout << "Concrete Visitor 2: Element A visited." << std::endl;
49+
}
50+
51+
void visitElementB(ConcreteElementB *) {
52+
std::cout << "Concrete Visitor 2: Element B visited." << std::endl;
53+
}
54+
};
55+
56+
/*
57+
* Element
58+
* defines an accept operation that takes a visitor as an argument
59+
*/
60+
class Element {
61+
public:
62+
virtual void accept(Visitor &visitor) = 0;
63+
};
64+
65+
/*
66+
* Concrete Elements
67+
* implement an accept operation that takes a visitor as an argument
68+
*/
69+
class ConcreteElementA : public Element {
70+
public:
71+
void accept(Visitor &visitor) {
72+
visitor.visitElementA(this);
73+
}
74+
};
75+
76+
class ConcreteElementB : public Element {
77+
public:
78+
void accept(Visitor &visitor) {
79+
visitor.visitElementB(this);
80+
}
81+
};
82+
83+
84+
int main()
85+
{
86+
ConcreteElementA elementA;
87+
ConcreteElementB elementB;
88+
89+
ConcreteVisitor1 visitor1;
90+
ConcreteVisitor2 visitor2;
91+
92+
elementA.accept(visitor1);
93+
elementA.accept(visitor2);
94+
95+
elementB.accept(visitor1);
96+
elementB.accept(visitor2);
97+
98+
return 0;
99+
}

0 commit comments

Comments
 (0)