¿Cómo copiar / crear una instancia de clase derivada desde un puntero a una clase base polimórfica?

He estado luchando con este tipo de problema durante mucho tiempo, así que decidí preguntar aquí.

class Base { virtual ~Base(); }; class Derived1 : public Base { ... }; class Derived2 : public Base { ... }; ... // Copies the instance of derived class pointed by the *base pointer Base* CreateCopy(Base* base); 

El método debe devolver una copia creada dinámicamente, o al menos almacenar el objeto en la stack en alguna estructura de datos para evitar el problema de “devolver la dirección de un problema temporal”.

El enfoque ingenuo para implementar el método anterior sería usar múltiples typeid o dynamic_cast en una serie de sentencias if para verificar cada posible tipo derivado y luego usar el new operador. ¿Hay algún otro enfoque mejor?

PD: Sé que este problema se puede evitar usando punteros inteligentes, pero estoy interesado en el enfoque minimalista, sin un montón de bibliotecas.

Agrega un virtual Base* clone() const = 0; en su clase base e implementarla de manera apropiada en sus clases Derivadas. Si su Base no es abstracta, puede llamar su copia-constructor, pero eso es un poco peligroso: si olvida implementarlo en una clase derivada, obtendrá (probablemente no deseado) un corte.

Si no desea duplicar ese código, puede utilizar el modificador CRTP para implementar la función a través de una plantilla:

 template  class DerivationHelper : public Base { public: virtual Base* clone() const { return new Derived(static_cast(*this)); // call the copy ctor. } }; class Derived1 : public DerivationHelper  { ... }; class Derived2 : public DerivationHelper  { ... }; 

Una alternativa es tener un método CreateCopy() virtual puro en la base común que se implementa en cada clase derivada.