Today interviewer told me that Visitor pattern & double dispatch can be used to call non-virtual method of derived class from 3rd party library which source code can't be accessed/changed (this is what they do in their production code, he said).
For example, in below code they pass reference to Animal
into Bar
and call specific methods of classes derived from Animal
without using dynamic_cast
. Point is that dynamic_cast
isn't used anywhere in their implementation. Templates aren't used.
I did rephrased my question to interviewer few times so there's no misunderstanding.
I don't see a way implementing Visitor without adding Accept
method to classes in library that will utilize argument overloading on Visitor::Visit
by passing *this
to it.
Is this possible? Or interviewer confused it with other language that probably allow something C++ doesn't? Because he was emphasizing that Visitor and double dispatch is used together, whereas AFAIK in C++ double dispatch is Visitor, meaning Visitor is used to implement double dispatch. I hope I didn't lost you. Thanks for your time!
import <iostream>;
namespace LibraryCode // can't be changed
{
class Animal
{
public:
virtual ~Animal() = default;
public:
virtual void move() const { std::cout << "Animal: moving!" << std::endl; };
void breath() const { std::cout << "Animal: breathing!" << std::endl; }
};
class Duck : public Animal
{
public:
void move() const override { std::cout << "Duck: flying!" << std::endl; }
void make_nest() const { std::cout << "Duck: making nest!" << std::endl; }
};
class Dolphin : public Animal
{
public:
void move() const override { std::cout << "Dolphin: swimming!" << std::endl; }
void make_air_bubble() const { std::cout << "Dolphin: making air bubble!" << std::endl; }
};
}
void Bar(LibraryCode::Animal const& a)
{
a.breath();
a.move();
// w/o using dynamic_cast call make_nest if it's a Duck
// w/o using dynamic_cast call make_air_bubble if it's a Dolphin
}
int main()
{
Bar(LibraryCode::Duck{});
Bar(LibraryCode::Dolphin{});
}