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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With