yandex
loader

please wait

  • Imran Malik Mar-14-2019 06:43:29 AM ( 1 week ago )

    The typical pattern when you want to copy a polymorphic class is adding a virtual clone method and implement it in each derived class like this:

    Base* Derived::clone()
    {
        return new Derived(*this);
    }

    Then in a calling code you can:

    Base *x = new Derived();
    Base *y = x->clone();

    However if you have 50+ derived classes and realize you need polymorphic copy, it's tedious to copy-paste the cloning method into each of them. And it's essentially a boilerplate that works around a language limitation that you have to spell out the actual name to call the constructor.

    I haven't keep track with the new features in recent C++ standards... Is there a way to avoid this in modern C++?

  • Harsh Vashishth Mar-14-2019 06:45:03 AM ( 1 week ago )

    You can use this generic CRTP code

    template <class Derived, class Base>
    struct Clonable : Base {
        virtual Base* do_clone() {
            return new Derived(*static_cast<Derived*>(this));
        }
        Derived* clone() { // not virtual
            return static_cast<Derived*>(do_clone());
        }
    
        using Base::Base;
    };
    
    struct empty {};
    struct A : Clonable<A, empty> {};
    struct B : Clonable<B, A> {};

    It can be generalised to smart pointers and multiple bases if desired.

  • Garry Buttler Mar-14-2019 06:46:56 AM ( 1 week ago )

    You probably have a class where you store the polymorphic object and where you want to clone? Together with your polymorphic object you could store a function-pointer doing the cloning:

    template<class Derived>
    Base* clone(const Base* b) {
        return new Derived(static_cast<const Derived*>(b));
    }
    
    void SampleUsage() {
        Base* b = new Derived;
        Base*(*cloner)(const Base*) = clone<Derived>;
        Base* copy = cloner(b);
    }

    The type of cloner is independent of Derived. Its like a simplified std::function.

Please login

Similar Discussion

Recommended For You