Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to have a collection of instances of classes all derived from the same base class?

I have a collection of classes all derived from a common base. I need a collection (probably a list) that will hold instances of derived classes of various types. Class operations will call virtual methods on the instances in the collection. Of course, I can't use list<Base> because holding the base class by value will slice the derived classes.

The obvious solution is to use list<Base*> and wrap it in a class with a copy constructor, a destructor, and so on. The base class would have a virtual duplicate function that is overloaded in each derived class to return a pointer to a copy-constructed new instance of that derived class. The destructor has to traverse the list and delete each item.

If there's a Boost way to do this, that's fine. I'm using Boost already. It seems to me that using Boost's shared pointers would be the best way. There would be overhead in managing the shared reference counts, but that's got to be less expensive than the allocate/copy required in the pointer case. However, this will mean that copies of the collection will result in the same instances and changing one copy will change the other.

I don't yet completely know how this code is going to actually be used. So I'm not sure if the shared copy semantics are going to be a problem. I don't think copies are going to be common, they just need to be handled sanely.

Is there another way?

like image 540
David Schwartz Avatar asked Sep 11 '25 10:09

David Schwartz


1 Answers

Say hello to Boost.PointerContainer. By default, these offer deep-copy semantics when you copy the containers (this is, however, customisable). Note that you need to implement a free new_clone method for your abstract base class in the appropriate namespace.

Also, as a side note, please use std::vector as your first-choice container.

Another side note, don't wrap the container<Base*>, but rather wrap the Base* in, you guessed it, a smart pointer. C++11 offers unique_ptr if you don't want shared ownership. unique_ptr only allows moving it, you can't copy it.

like image 82
Xeo Avatar answered Sep 12 '25 23:09

Xeo