#include <iostream>
#include <memory>
struct Visitor;
struct Shape {
virtual void accept(std::unique_ptr<Visitor> v) = 0;
};
struct Circle : Shape { void accept(std::unique_ptr<Visitor> v) override; };
struct Triangle : Shape { void accept(std::unique_ptr<Visitor> v) override; };
struct Square : Shape { void accept(std::unique_ptr<Visitor> v) override; };
struct Point {
Point(float x, float y) {}
};
struct Visitor {
virtual void visit(Circle &c) const = 0;
virtual void visit(Triangle &t) const = 0;
virtual void visit(Square &s) const = 0;
};
void Circle::accept(std::unique_ptr<Visitor> v) {
v->visit(*this);
}
void Triangle::accept(std::unique_ptr<Visitor> v) {
v->visit(*this);
}
void Square::accept(std::unique_ptr<Visitor> v) {
v->visit(*this);
}
struct SnapToPoint : Visitor {
SnapToPoint(float x, float y) : _point(x, y) {}
void visit(Circle &c) const override { std::cout << "Snapped a Circle\n"; }
void visit(Triangle &t) const override { std::cout << "Snapped a Triangle\n"; }
void visit(Square &s) const override { std::cout << "Snapped a Square\n"; }
private:
Point _point;
};
struct ShapeOperationFactory {
virtual std::unique_ptr<Visitor> snapToPoint(float x, float y) const = 0;
};
struct MyShapeOpFactory : ShapeOperationFactory {
std::unique_ptr<Visitor> snapToPoint(float x, float y) const override {
return std::unique_ptr<Visitor>(new SnapToPoint(x, y));
}
};
int main() {
Shape *pShape = new Circle;
ShapeOperationFactory *pFactory = new MyShapeOpFactory;
pShape->accept(pFactory->snapToPoint(4.0f, 7.0f));
delete pFactory;
delete pShape;
return 0;
}