masterinex wrote: |
---|
Do i need to create the objects dynamically with the new keyword in order to make polymorphism work ?
lets say i create these objects statically:
Circle c1(1, 1, 1);
|
Using "dynamic" vs "static" this way is not quite how these words are used in C++ literature and programmer communication. There is nothing "static" about creating an object this way.
dynamic polymorphism takes place when static type of an expression differs from the dynamic type of the object that expression refers to, and you make a virtual member function call:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include <iostream>
#include <cmath>
struct Shape {
virtual double area() const = 0;
virtual ~Shape() = default;
};
struct Circle : Shape {
double x,y,r;
Circle(double x, double y, double r) : x(x), y(y), r(r) {}
double area() const override { return std::acos(-1)*r*r; }
};
void demo(const Shape& s) {
std::cout << s.area(); // <- here is the runtime-polymorphic code
}
int main()
{
Circle c1(1, 1, 1);
demo(c1);
}
|
live:
https://wandbox.org/permlink/JsSrvUGKZ74kfiph
in this demo, dynamic polymorphism takes place inside the function demo, when the expression "s.area()" is executed.
The static type of "s" in that function is "Shape", the dynamic type of "s" is "Circle", so the call to s.area() chooses, at run time, Circle::area instead.
If I then do
1 2
|
Line l4(1, 1, 2, 2);
demo(l4);
|
, the very same function "demo", at the very same line s.area(), will call a different function, Line::area. This is what "polymorphism" means: same code does different things.
Everything else - pointers, containers, etc - is just added layers on top of this core concept.
(and yes, don't use shared pointers if you're not sharing ownership between multiple threads or otherwise unpredictably terminating owners. Use std::unique_ptr if you need a container that owns a bunch of heap-allocated objects of different type with a common base:
1 2 3
|
std::vector<std::unique_ptr<Shape>> v;
v.push_back(std::make_unique<Circle>(1,1,1));
v.push_back(std::make_unique<Line>(1,1,2,2));
|
that alone is not an example of runtime polymorphism though: it will only happen when you make a call to a Shape's virtual member function, perhaps like this:
1 2
|
for(const auto& p : v)
std::cout << p->area(); // polymorphic call here
|
)