The issue I am having is the following: I have an inheritance hierarchy of objects, and I want to define a class that represents a collection of objects from this hierarchy that can have different dynamic types. I am wondering if there is a way to make and iterate over such a collection while hiding the fact that it contains pointers. Currently my code can be summarized as follows :
class Base{
public:
virtual Base* clone() const & { return new Base(*this); }
virtual Base* clone() && { return new Base( std::move(*this) ); }
... other members ...
};
class Derived : public Base{
public:
Derived* clone() const & override { return new Derived(*this); }
Derived* clone() && override { return new Derived( std::move(*this) ); }
... other members ...
};
class ObjectCollection{
public:
... constructor and other members...
// use 'clone' function to initialize the collection without having to pass pointers
void push_back( const Base& );
void push_back( Base&& );
using iterator = std::vector< std::shared_ptr< Base > >::iterator
using const_iterator = std::vector< std::shared_ptr< Base > >::const_iterator
iterator begin(){ return collection.begin(); }
const_iterator begin() const{ return collection.cbegin(); }
iterator end() { return collection.end(); }
const_iterator end() const{ return collection.cend(); }
private:
std::vector< std::shared_ptr< Base > > collection;
};
//loop over objects:
ObjectCollection collection(...call to constructor...);
for( auto & object : collection ){
//object is now a reference to shared_ptr to Object rather than a reference to Object!
}
Ideally I would like to be able to write a for loop like the last one, where I can get references to the objects directly rather than pointers. Is there a way to achieve this? Or would it be better to keep working with pointers? (Note: one way I know of to solve the problem, but which I would like to avoid, is to overload the [] operator to already dereference the pointers).