Search code examples
c++c++11inheritanceclone

c++ clone function in abstract class


in c++11 standard, if class B inherits from class A, then 'B is an A'. However, i am still confused regarding this notion: look at this code:

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

class Derived : public Base {
public:
    virtual Base* clone() const {
        return new Derived(*this);
    }
    //<more functions>
};

we returned a pointer to Base from Derived, but if using this approach in this code:

Derived* d1 = new Derived();
Derived* d2 = d1->clone();

what we did is assigning Base* in Derived*!!

The Problem:
why this code does not compile? How could it be modified(and why?) in order to fit with the inheritance?


Solution

  • The code you posted will not compile even after some trivial edits (which I made). The signature of the Derived::clone() should be:

    virtual Derived* clone() const override {  // <-- return type
      return new Derived(*this);
    }
    

    Even though the return type of clone() in Base and Derived class are different, it's a valid overriding of virtual function because, the co-variance is legal in C++.

    There won't be any slicing when you deal with the pointers as stated in your question.
    Derived::clone() should return Derived*.

    Whether the clone() should be virtual or not depends on the design, but with virtual destructor it's a good idea.


    Another approach is to use a template and avoid virtual:

    class Base {
    public: 
        virtual ~Base() {}
        template<class T>  // now need not add this trivial code in all derived classes
        T* clone() const { return new T(*this); }
    };