@
vittorioc98
In your OP, the first part of the code in the main function (lines 2 to 4)shows how it doesn't work. Because it has the slicing which
keskiverto explains.
Lines 6 to 8 shows how it does work. Because it pushes a pointer of Derived into a container which expects a pointer to Base, which is OK as mentioned by
Yolandaand shown again by me, below. It need not be a shared pointer, a normal pointer is OK too.
The example in the OP is not a good one because it only puts 1 thing into the container. It's more demonstrative if there are several different types in the container.
http://www.cplusplus.com/doc/tutorial/polymorphism/
And this posted by
Yolanda earlier, emphasis by me:
One of the key features of class inheritance is that a pointer to a derived class is
type-compatible with a pointer to its base class. Polymorphism is the art of taking advantage
of this simple but powerful and versatile feature. |
One way of looking at this a container of Shape :
std::vector<Shape*> AllTheShapes;
Shape is the
base class with a pure virtual area function, the derived classes might be triangle, regularpolygon, circle etc. They all have their own version of the area member function.
Now we fill this vector with
pointers to the derived class objects. The compiler calls the correct derived area function because it has a pointer to the derived class object, but it needs to check as described in the next paragraph.
Because it is a container of Base class pointers, only base class functions can be called. But this is OK because the derived classes have their own version of the function in the base class. This is known as the interface - that is, the public functions in the base class a user can call to interact with all the derived class objects.
Next iterate through all the items in the vector, and call the area function. The compiler does the right thing
This is a really big advantage:
* We write std::vector<Base*> ,
we do not have:
std::vector<Triangle> Triangles;
std::vector<regularpolygon> Regularpolygons;
std::vector<circle> Circles;
and having to add more of these if we add another type of Shape, and change all the code everywhere so it works with the new type.
When we use Polymorphism, we can can add a new type Shape like
class ellipse : public Shape {};
all we have to do is define an area function for it, and all the other code still works.
So we can have a lot less number of containers, and a lot less numbers of functions.
This also demonstrates how naming is important. We have a function in each derived class, all with the same name - area. We don't have TriangleArea, CircleArea etc.
I was looking for an example of code online, but all the examples I found had aspects I didn't like. Hopefully my explanation is sufficient :+)