The purpose of that behavioral design pattern is to add a new operation without adding it to the existing object structure.
#include <iostream>
class Cat;
class Dog;
class IPetVisitor
{
public:
virtual void visit(Dog* dog) = 0;
virtual void visit(Cat* cat) = 0;
};
class Pet
{
public:
virtual void accept(IPetVisitor* petVisitor) = 0;
virtual std::string getSound() = 0;
virtual ~Pet() {}
};
class Cat : public Pet
{
public:
void accept(IPetVisitor* petVisitor)
{ if(petVisitor) {petVisitor->visit(this);} }
std::string getSound()
{ return std::string("meow"); }
};
class Dog : public Pet
{
public:
void accept(IPetVisitor* petVisitor)
{ if(petVisitor) {petVisitor->visit(this);} }
std::string getSound()
{ return std::string("woof"); }
};
class PetVisitor : public IPetVisitor
{
public:
void visit(Cat* cat)
{ std::cout << "The cat does " << cat->getSound() << std::endl; }
void visit(Dog* dog)
{ std::cout << "The dog does " << dog->getSound() << std::endl; }
};
int main()
{
PetVisitor petVisitor;
Cat cat;
cat.accept(&petVisitor);
Dog dog;
dog.accept(&petVisitor);
return 0;
}