3

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{});
}
Soup Endless
  • 439
  • 3
  • 10
  • 1
    make `Bar` a template? – Alan Birtles Oct 12 '22 at 19:05
  • Check this https://stackoverflow.com/questions/7489067/implicit-upcasting-question – jmchen Oct 12 '22 at 19:07
  • 1
    Probably the library (that you cannot change) has a visit() function with an appropriate visitor. Then you can do dynamic visitation. Either that, or they have (essentially) a variant and do a (static) visit on that. – lorro Oct 12 '22 at 19:07
  • @AlanBirtles was my first guess to use metaprogramming, but not. Templates aren't used. Thanks for mentioning it. – Soup Endless Oct 12 '22 at 19:07
  • @lorro is this common practice for library developers to put virtual `Visit` function in hierarchy? I doubt it was `std::variant` as no templates were involved in solution. – Soup Endless Oct 12 '22 at 19:13
  • 1
    @SoupEndless It was before variants became preferred (for performance reasons). – lorro Oct 12 '22 at 19:31
  • 2
    Don't trust any random interviewer. He's a software developer after all. He's probably just as confused as an average visitor of this site. – n. m. could be an AI Oct 12 '22 at 20:00

0 Answers0