Visitor is a behavioral design pattern that lets you separate algorithms from the objects on which they operate.
For example you have a class Circle, Square, initially you added a functionality to provide area.
Now, there is requirement that you want to provide perimeter as well, or some other stuff.
You could say, well, we can directly add these methods in Circle and Square classes, which sounds okay, but like if there are so many classes and You don’t want to touch circle and Square, as adding something new to existing classes is always risky.
Also, if you keep on adding new functionality in these classes, then it is violation of Open-Closed principle { which says classes should be open for extension but closed for modification }
Coming back to our problem, so we want to decouple our alogrithm from the class. Visitor pattern is for the resuce.
Every class can accept IVisitor (visitor interface ), then there will be concrete visitors implementing the acutal funcationalities.
In this case, we can have IVisitor to have visitSquare, VisitCircle and these can contain the reference of the Square and Circle objects.
ConcreteVisitor will be passed to Shape’s visit, this will pass Shape’s reference to ConcreteVisitor

class IVisitor;
class Circle;
class Square;
class IShape {
public:
virtual ~IShape() {}
virtual void visit(shared_ptr<IVisitor> & visitor) = 0;
};
class IVisitor {
public:
virtual ~IVisitor() {};
virtual void visitSquare(Square &obj) = 0;
virtual void visitCircle(Circle &obj) = 0;
};
class AreaVisitor : public IVisitor {
public:
void visitSquare(Square &obj);
void visitCircle(Circle &obj);
};
class Circle : public IShape {
private:
float mRadius;
public:
Circle (float radius) : mRadius(radius) {
cout <<" circle cons" <<endl;
}
void visit(shared_ptr<IVisitor> & visitor);
float getRadius() { return mRadius; }
};
class Square : public IShape {
float mSide;
public:
Square (float side) : mSide (side) {
cout <<" Square cons" <<endl;
}
void visit(shared_ptr<IVisitor> & visitor);
float getSide () { return mSide; }
};
void AreaVisitor::visitCircle(Circle &obj) {
auto area = 22/7 * obj.getRadius() * obj.getRadius();
cout <<" circle area " << area <<endl;
}
void AreaVisitor::visitSquare(Square &obj) {
auto area = obj.getSide() * obj.getSide();
cout <<" square area " << area <<endl;
}
void Circle::visit(shared_ptr<IVisitor>& visitor) {
visitor->visitCircle(*this);
}
void Square::visit(shared_ptr<IVisitor>& visitor) {
visitor->visitSquare(*this);
}
int main() {
Square c(7);
shared_ptr<IVisitor> av = make_shared<AreaVisitor>();
c.visit(av);
}
Follow more posts @ https://jdecodes.wordpress.com
My all design pattern articles :
- https://jdecodes.wordpress.com/2024/07/13/builder-design-pattern/
- https://jdecodes.wordpress.com/2024/07/13/command-design-pattern/
- https://jdecodes.wordpress.com/2024/07/13/iterator-design-pattern/
- https://jdecodes.wordpress.com/2024/07/13/mediator-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/state-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/memento-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/observer-design-pattern/
- https://jdecodes.wordpress.com/2024/07/19/strategy-pattern/
- https://jdecodes.wordpress.com/2024/07/20/visitor-design-pattern/
- https://jdecodes.wordpress.com/2024/07/20/adapter-desing-pattern/
- https://jdecodes.wordpress.com/2024/07/20/bridge-design-pattern/
- https://jdecodes.wordpress.com/2024/07/22/composite-desing-pattern/
- https://jdecodes.wordpress.com/2024/07/22/facade-design-pattern/
- https://jdecodes.wordpress.com/2024/07/22/decorater-design-pattern/
Leave a comment