c++inheritanceclone

C++ elegantly clone derived class by calling base class


I have a need to clone a derived class given only a reference or pointer to the base class. The following code does the job, but doesn't seem elegant, because I'm putting boilerplate code into many derived classes C, D, E that are siblings of B (not shown) that just calls the default copy constructor of each. Isn't that what the default copy constructor is for, if only it could be virtual?

Is there a better way?

Making a virtual assignment operator would be wrong, as I don't want C to assign to B, B to D, etc, just clone B, C, D or E.

#include <iostream>
using namespace std;

class A {
public:
    virtual ~A() {}
    virtual A* clone()=0;
};

class B : public A {
    int i;
    public:
    virtual A* clone() { 
        cout << "cloned B" << endl;
        return new B(*this);
    }
    virtual ~B() { cout << "destroyed b" << endl; }
};

int main() { 
    A* a = new B(); 
    A* aa = a->clone();
    delete a; 
    delete aa; 
    return 0;
}

Solution

  • You could always stick all the cloning logic into its own class in the middle of the hierarchy:

    template <class Derived, class Base>
    class CloneCRTP : public Base {
    public:
        Derived* clone() const override {
            return new Derived(static_cast<Derived const&>(*this));
        }
    };
    

    And then:

    class B : public CloneCRTP<B, A>
    {
        int i;
    public:
        virtual ~B() { cout << "destroyed b" << endl; }        
    };
    

    No more boilerplate.