The vector
container owns every object in it, specifically constructing the object to become part of the vector. Since you cannot construct a Shape
to go into the vector, there would be no way to use std::vector<Shape>
. Try to insert an object into that vector, it cannot be done.
On the other hand, a pointer to an instance of any class derived from Shape
can be converted to a Shape*
, and you can copy pointers with no problem. So this is fine:
vector<Shape*> vps;
vps.insert(new Circle());
Similarly, unique_ptr
s are polymorphic. So you can construct a unique_ptr<Shape>
that points to an instance of a class derived from Shape
.
But there is no way you can make a Shape
that is an instance of a class derived from Shape
. So vector<Shape>
is a non-starter.
Another way to see it is to look at what space the vector will allocate. For a vector of Shape*
, it will allocate enough space to hold a Shape*
, and that can hold a pointer to an instance of a class derived from Shape
, no problem.
For a vector of unique_ptr<Shape>
, that will allocate enough space to hold a unique_ptr<Shape>
, and that can hold a unique pointer to a Shape
that points to a class derived from Shape
, no problem.
But what happens with vector<Shape>
. That allocates enough space to hold a Shape
. But what can we do with that if we're trying to store a class derived from Shape
? There is nothing at all we can do with that space! Instances of derived classes are typically larger than instances of their base classes, so such a vector would again be useless to us.