zeus

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

commit 37ffe2c5a7871bd8d0463b4d2b35ce16377f1c30
parent af6947bdb404578a8567b72ad3460c6c16e42b8e
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Sun, 18 May 2025 20:36:24 +0200

Acyclic Visitor

Diffstat:
A visitor_acyclic.cpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 files changed, 95 insertions(+), 0 deletions(-)


diff --git a/ visitor_acyclic.cpp b/ visitor_acyclic.cpp

@@ -0,0 +1,95 @@

#include <cassert>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>

class PetVisitor {
public:
virtual ~PetVisitor() = default;
};

class Pet {
std::string m_color;

public:
virtual ~Pet() = default;
Pet(std::string_view color) : m_color(color) {};

virtual void accept(PetVisitor &v) = 0;

const std::string &color() const { return m_color; }
};

class Cat;

class CatVisitor {
public:
virtual void visit(Cat *c) = 0;
};

class Cat : public Pet {
public:
using Pet::Pet;

void accept(PetVisitor &v) override {
if (CatVisitor *cv = dynamic_cast<CatVisitor *>(&v)) {
cv->visit(this);
} else {
assert(false);
}
};
};

class Dog;

class DogVisitor {
public:
virtual void visit(Dog *d) = 0;
};

class Dog : public Pet {
public:
using Pet::Pet;

void accept(PetVisitor &v) override {
if (DogVisitor *cv = dynamic_cast<DogVisitor *>(&v)) {
cv->visit(this);
} else {
assert(false);
}
};
};

class FeedingVisitor : public PetVisitor, public CatVisitor, public DogVisitor {
public:
void visit(Cat *c) override {
std::cout << "Feed tuna to the " << c->color() << " cat\n";
}

void visit(Dog *c) override {
std::cout << "Feed streak to the " << c->color() << " dog\n";
}
};

class BathingVisitor : public PetVisitor, public DogVisitor {
public:
void visit(Dog *c) override {
std::cout << "Wash the " << c->color() << " dog\n";
}
};

int main() {
std::unique_ptr<Pet> c(new Cat("orange"));
std::unique_ptr<Pet> d(new Dog("brown"));

FeedingVisitor fv;
c->accept(fv);
d->accept(fv);

BathingVisitor bv;
// c->accept(bv);
d->accept(bv);

return 0;
}