Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy/create derived class instance from a pointer to a polymorphic base class?

I have been struggling with this kind of problem for a long time, so I decided to ask here.

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); 

The method should return a dynamically created copy, or at least store the object on stack in some data structure to avoid "returning address of a temporary" problem.

The naive approach to implement the above method would be using multiple typeids or dynamic_casts in a series of if-statements to check for each possible derived type and then use the new operator. Is there any other, better approach?

P.S.: I know, that the this problem can be avoided using smart pointers, but I am interested in the minimalistic approach, without a bunch of libraries.

like image 341
eold Avatar asked Apr 20 '11 13:04

eold


People also ask

Can you convert a pointer from a derived class to its base class?

[19.4] Is it OK to convert a pointer from a derived class to its base class? Yes.

Can you assign a derived class object to a base class object?

Object Slicing in C++ In C++, a derived class object can be assigned to a base class object, but the other way is not possible.

How do you create a derived class of base class?

When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.

Can a base class be derived from a derived class?

The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class. However, inheritance is transitive.


2 Answers

You add a virtual Base* clone() const = 0; in your base class and implement it appropriately in your Derived classes. If your Base is not abstract, you can of course call its copy-constructor, but that's a bit dangerous: If you forget to implement it in a derived class, you'll get (probably unwanted) slicing.

If you don't want to duplicate that code, you can use the CRTP idiom to implement the function via a template:

template <class Derived> class DerivationHelper : public Base { public:   virtual Base* clone() const   {     return new Derived(static_cast<const Derived&>(*this)); // call the copy ctor.   } };  class Derived1 : public DerivationHelper <Derived1> { ... }; class Derived2 : public DerivationHelper <Derived2> { ... }; 
like image 63
ltjax Avatar answered Oct 14 '22 10:10

ltjax


An alternative is to have a pure virtual CreateCopy() method in the common base that is implemented in each derived class.

like image 26
sharptooth Avatar answered Oct 14 '22 10:10

sharptooth