With polymorphic objects you cannot reserve just enough storage for the base class and then expect to be able to jam any derived class into that space. That's what you're doing when you say:
list<allShapes> shapes;
Any time you try to jam a line
into the space for an allShapes
object, what will happen is that the allShapes
part of the line
will get stored, and the line
part will be ignored. So then you've got an object that is not a line
, and calling .draw()
on it will not call the line::draw()
. It will call the correct draw()
method given the dynamic type of the object, which is allShapes
.
And the same thing happens again when you say:
allShapes check = shapes.front();
check.draw();
Whatever type results from shapes.front()
is converted into allShapes
. If you had a list of line
s then it would be converted to allShapes
here.
Using polymorphism generally requires using pointers or references:
list<unique_ptr<allShapes>> shapes;
Now you can put lines into this collection:
shapes.push_back(make_unique<line>()); // make_unique is C++14
This way the line
does not get converted into an allShapes
, and so when virtual dispatch is done to find the correct method based on the object's real dynamic type, the draw()
method for line
will be used.
In order to access an object in the list you can use a reference:
allShapes &check = shapes.front();
check->draw();
If you're coming to C++ from a language that uses reference types by default, such as Java or C#, then you really need to understand how C++ value types work. In those other languages you use pointers all over the place but the syntax doesn't make that obvious. To use pointers in C++ you have to explicitly use special pointer syntax.
You might find another answer where I cover this useful: Confused with object arrays in C++