What's the preferred C++ idiom to own a collection of polymorphic objects?

c++, c++11, polymorphism

Solution

Polymorphic objects have to be handled by pointer or reference. Since their lifetime is probably not bound to a particular scope they will also probably have dynamic storage duration, which means you should use a smart pointer.

Smart pointers such as `std::shared_ptr` and `std::unique_ptr` work just fine in the standard collection types.

std::vector<std::unique_ptr<Base>>

Using this in `Owner` looks like:

class Owner {
public:
    void do_all_stuff() {
        //iterate through all items and call do_stuff() on them
    }

    void add_item(std::unique_ptr<Base> item) {
        items.push_back(std::move(item));
    }

    vector<std::unique_ptr<Base>> items;
}

The argument type to `add_item` identifies the ownership policy required for adding an item, and requires the user to go out of their way to screw it up. For example they can't accidentally pass a raw pointer with some implicit, incompatible ownership semantics because `unique_ptr` has an explicit constructor.

`unique_ptr` will also take care of deleting the objects owned by `Owner`. Although you do need to ensure that `Base` has a virtual destructor. With your current definition you will get undefined behavior. Polymorphic objects should pretty much always have a virtual destructor.

Problem

Consider the following classes ``` class Base { public: virtual void do_stuff() = 0; }; class Derived : public Base { public virtual void do_stuff() { std::cout << "I'm useful"; }; }; ``` Now let's say I want to have another class responsible for owning objects of `Base`'s derived types and iterate through them calling their `do_stuff()` method. It looks like this, but I don't know what `T` should be declared as ``` class Owner { public: void do_all_stuff() { //iterate through all items and call do_stuff() on them } void add_item(T item) { items.push_back(item); } vector<T> items; } ``` I see a few possibilities: `T` can't be `Base`, since I would only be able to add objects of concrete type `Base`, so that's out of the question. `T` can be `Base*` or `Base&`, but now I need to trust the caller of `add_item()` to pass me a pointer or a reference to an object that will still exist when I retrieve it from `items`. I can't `delete` the elements in `Owner`'s destructor, since I don't know that they were dynamically allocated. However, they should be `delete`'d if they were, which leaves me with ambiguous ownership. `T` can be `Base*` or `Base&` and I add a `Base* create_item<DerivedT>() { return new DerivedT; }` method to `Owner`. This way, I know the pointer will remain valid and I own it, but I'm unable to call a non-default constructor on `DerivedT`. Also, `Owner` becomes responsible for instantiating objects as well. I also have to delete every item in `Owner`'s destructor, although that's not much of an issue. Basically, I'd like to be able to do something similar to: ``` Owner owner; void add_one() { Derived d; owner.add_item(d); } void ready() { owner.do_all_stuff(); } void main() { for(int i = 0; i < 10; ++i) { add_one(); } ready(); } ``` I'm sure there's something related to move semantics in there (I could move the objects passed to `add_items()` to own them) but I still can't figure out how my collection would be declared. What is the C++ idiom for this sort of polymorphic ownership (particularly with STL containers)?

Original source