Is it possible to clone a polymorphic object without manually adding overridden clone method into each derived class in C++?

General Tech Bugs & Fixes 2 years ago

0 3 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Bugs & Fixes related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (3)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years 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++?

profilepic.png
manpreet 2 years 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.


0 views   0 shares

profilepic.png
manpreet 2 years 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.


0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.