I have two class that inherit the same abstract base class:
class base
{ virtual void something() = 0; };
class a : public base
{
void something();
};
class b : public base
{
void something();
// This is what I want: a list where I can store values of type a
// and of type b
// std::list<a & b> objs;
};
I could use a list of raw/smart pointers (list<base*> obj_ptrs), but how to use this list?
b b_obj;
b_obj.obj_ptrs.push_back(new a());
// Who have to delete this pointer? Who use the class or who design
// the class in the object destructor?
// The following is valid for c++11
auto p = b_obj.obj_ptrs.back();
// But if i'm using c++03?
I want that who use the class have the possibility to do this:
a a_obj;
b b_obj;
b_obj.obj_ptrs.push_back(a);
b_obj.obj_ptrs.push_back(b);
How have I to design my classes to do this work?
You would interact with them polymorphically by calling virtual functions or, in exceptional circumstances, using
dynamic_castto convert the pointer type toa*orb*.You will have to decide on the ownership scheme. One approach is to store smart pointers (usually
unique_ptr, or perhapsshared_ptrin special circumstances) in the list, and then they’ll be automatically deleted on removal from the list. Another approach is to manage the objects separately from the list, and just put raw pointers in the list.That’s equivalent to
base * p = b_obj.obj_ptrs.back();.autowill not magically give the dynamic pointer type, it’s just a shortcut for the static pointer type.Storing objects of different types can be done using a discriminated union – basically, a union with some extra metadata to keep track of which union member is active. These are quite tricky to implement in C++, but you could use Boost.Variant or Boost.Any. This has the advantage that you don’t need a common base class, or any other support from the types being stored; any set of (non-abstract) types can be used.