Visitor (Design pattern)

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;
}