Carlton
Carlton

Reputation: 4297

Cloning a derived type more elegantly

I have a pure virtual base class and several derived classes, and I need to clone the derived's. I did this initially:

struct base {
   virtual base* clone() = 0;
}

struct derived: public base {
   base* clone() {
      derived* d = new derived;
      /*copy members, etc.*/
      return d;
   }
}

This works fine, except that the clone function implementations in all my derived classes are IDENTICAL except for the returned type (which will be one of the derived types). In other words, all the operations that I do during the cloning process are common to the base class. So, the next thing I did was add a template function to my base class:

struct base {
   virtual base* clone() = 0;

   template <typename T>
   T* make_clone() {
      T* d = new T;
      /*copy members, etc.*/
      return d;
   }
}

struct derived: public base {
   base* clone() {return base::make_clone<derived>();}
}

This works too, but it seems a bit inelegant and I feel like there should be a cleaner approach with fewer function calls and elimination of the one-line functions in all my derived classes. Is there some language feature or design pattern that I can play with to clean this up a bit? Also just to clarify, the caller does not know the derived type of the base* that it needs to clone. Otherwise I could just call base::make_clone<derived> directly.

Upvotes: 1

Views: 132

Answers (1)

filmor
filmor

Reputation: 32288

You could use the CRTP:

template <typename Derived>
struct derived_base : base
{
    Derived* clone()
    {
        Derived* x = new Derived;
        // ...
        return x;
    }
};

struct derived : derived_base<derived> {}

Upvotes: 1

Related Questions