zeus

Unnamed repository; edit this file 'description' to name the repository.
git clone Unknown
Log | Files | Refs

visitor_acyclic.cpp (1685B)


0 #include <cassert>
1 #include <iostream>
2 #include <memory>
3 #include <string>
4 #include <string_view>
6 class PetVisitor {
7 public:
8 virtual ~PetVisitor() = default;
9 };
11 class Pet {
12 std::string m_color;
14 public:
15 virtual ~Pet() = default;
16 Pet(std::string_view color) : m_color(color) {};
18 virtual void accept(PetVisitor &v) = 0;
20 const std::string &color() const { return m_color; }
21 };
23 class Cat;
25 class CatVisitor {
26 public:
27 virtual void visit(Cat *c) = 0;
28 };
30 class Cat : public Pet {
31 public:
32 using Pet::Pet;
34 void accept(PetVisitor &v) override {
35 if (CatVisitor *cv = dynamic_cast<CatVisitor *>(&v)) {
36 cv->visit(this);
37 } else {
38 assert(false);
39 }
40 };
41 };
43 class Dog;
45 class DogVisitor {
46 public:
47 virtual void visit(Dog *d) = 0;
48 };
50 class Dog : public Pet {
51 public:
52 using Pet::Pet;
54 void accept(PetVisitor &v) override {
55 if (DogVisitor *cv = dynamic_cast<DogVisitor *>(&v)) {
56 cv->visit(this);
57 } else {
58 assert(false);
59 }
60 };
61 };
63 class FeedingVisitor : public PetVisitor, public CatVisitor, public DogVisitor {
64 public:
65 void visit(Cat *c) override {
66 std::cout << "Feed tuna to the " << c->color() << " cat\n";
67 }
69 void visit(Dog *c) override {
70 std::cout << "Feed streak to the " << c->color() << " dog\n";
71 }
72 };
74 class BathingVisitor : public PetVisitor, public DogVisitor {
75 public:
76 void visit(Dog *c) override {
77 std::cout << "Wash the " << c->color() << " dog\n";
78 }
79 };
81 int main() {
82 std::unique_ptr<Pet> c(new Cat("orange"));
83 std::unique_ptr<Pet> d(new Dog("brown"));
85 FeedingVisitor fv;
86 c->accept(fv);
87 d->accept(fv);
89 BathingVisitor bv;
90 // c->accept(bv);
91 d->accept(bv);
93 return 0;
94 }