0

I would like to know if there is a "default" approach to get a copy of a object of a derived class.

My class structure looks like this:

 |------> A <------|
 |        ^        |
 |        |        |
B1        B2       B3

Hereby, A is an abstract base class, which has a private B* member child_. Now, I would like to define the following method in A:

void set_child(const A& new_child) {
     if (child_ != nullptr)
         delete child_;
     // Now I want a to create a copy of new_child
     // (of the most specific derived class),
     // without explicitly dispatching on its type.

     child_ = ???

     // I think, child_ = new A(child); does not work
}

What would be the most canonical way to do this? I thought about defining a virtual clone() method in each derived class, so that I could write

child_ = new_child.clone();

but then I have to touch every derived class.

I would be glad for your recommendations.

Thank you, Sven

Sven Hager
  • 3,144
  • 4
  • 24
  • 32
  • 2
    [CRTP](http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) might be useful here.. – Marco A. Jul 28 '14 at 15:10
  • Excuse me, what is CRTP? – Sven Hager Jul 28 '14 at 15:10
  • 2
    Look at this: `if (child_ == nullptr) delete child_;`? Did you mean `!=`? – wjl Jul 28 '14 at 15:11
  • Added link, sorry for not having done that before. I was just thinking though – Marco A. Jul 28 '14 at 15:11
  • 2
    Exactly what I was thinking: http://stackoverflow.com/a/5731259/1938163 – Marco A. Jul 28 '14 at 15:12
  • 3
    possible duplicate of [How to copy/create derived class instance from a pointer to a polymorphic base class?](http://stackoverflow.com/questions/5731217/how-to-copy-create-derived-class-instance-from-a-pointer-to-a-polymorphic-base-c) – Marco A. Jul 28 '14 at 15:12
  • 5
    @SvenHager - There is no need to check for a null pointer when issuing a `delete`. – PaulMcKenzie Jul 28 '14 at 15:15
  • You need a semicolon after `???` – scohe001 Jul 28 '14 at 15:34
  • If you know the type of the child before entering this function, you can copy construct the child out of this function and then pass it in. You don't need to add clone method this way. Otherwise, you have to define clone virtual method. – Hsi-Hung Shih Jul 28 '14 at 17:26
  • Just out of curiosity: do you actually need to store a copy of the child object or would a reference/pointer be enough? Meaning, if you call setChild on two object a1 and a2 with the same child, do you need the child of a1 and a2 to be always in sync (or at least, is it ok if they are)? Cause if this is the case, you could use a shared_ptr (passing a shared_ptr rather than a reference, of course) and forget about the whole cloning problem. – bartgol Jul 28 '14 at 22:33

1 Answers1

0

There at two issues at stake here:
1. The base class has no idea of the size of the child class.
2. The child class is variable (in content) and you don't want to copy different types.

The most popular solution is the "clone" solution, in which the child class returns a pointer to a dynamically allocated copy of itself.

By the way, you will need to make the clone before you delete the old child.

Search the web for "C++ clone design pattern".

Reminder: also review whether you want a smart pointer, and if so, which one.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154