I have different types, say A
, B
, C
, that all inherit from some base class Base
:
class Base { ... };
class A : public Base { ... };
class B : public Base { ... };
class C : public Base { ... };
I need a container, let's call it Master
, that holds pointers to objects of types A
, B
and C
. I want the Master
container to provide an iterator over all contained Base
objects, as well as specifically-typed iterators over all contained A
, B
and C
objects. As a storage backend, I'll be using std::vector
, but it would be nice if this can be switched easily later on.
Conceptually, this is the interface that Master
should present to the outside world:
class Master {
public:
add(A *a);
add(B *b);
add(C *c);
remove(Base *base);
iterator<A*> a_begin();
iterator<A*> a_end();
iterator<B*> b_begin();
iterator<B*> b_end();
iterator<C*> c_begin();
iterator<C*> c_end();
iterator<Base*> base_begin();
iterator<Base*> base_end();
// also: reverse iterators, const iterators, reverse const iterators
};
The interface does not have to match this precise syntax. For example, someMaster.begin<A>()
is perfectly fine too.
The trouble is, even in this simplified interface, you can already see some code duplication happening. It's much worse in the implementation. This is unacceptable, because I want to be able to extend the Master
container easily later on, if I want to add classes D
, E
and F
(also inheriting from Base
). Preferably, I would like to extend it with just one or two lines of code.
All this could be implemented with lots of dynamic_cast
ing, but that's ugly. I think some magic with templates and multiple inheritance could help me out here. What would be the cleanest implementation of this class?