Consider the following classes
class Base {
public:
virtual void do_stuff() = 0;
};
class Derived : public Base {
public
virtual void do_stuff() { std::
Assuming from your context that Owner
is the sole owner of the contained objects,T
should be unique_ptr<Base>
(where unique_ptr
comes from boost or std depending on your C++11 availability). This properly recognizes that it's solely owned by the container and additionally shows the ownership transferral semantics in your add_item
call.
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.
Other alternatives worth considering are to use boost::ptr_container
, or even better, use a library like adobe::poly
or boost::type_erasure
for your polymorphic types, to exploit value-based run-time polymorphism—avoids the need for pointers, inheritance, etc.
Actually you cannot store references in STL, only pointers or real values. So T is Base* Try other things you will have your compiler complaining.