Lets say you've 3 different cars. And you've different mechanisms of driving them. The driver needn't know about the underlying engines but only the protocol of how to drive a car i.e. press this pedal for acceleration, press that pedal for brakes, etc.
Now from the driver's perspective, it doesn't matter if its Honda, Ford or Buick. From his viewpoint, it is just a car. Likewise, if you've shed, where cars are parked, you call them a car shed. It houses cars and isn't bothered about what make each one is. So
std::vector<Car*> v;
v.push_back(new Ferrari());
v.push_back(new Honda());
v.push_back(new Ford());
why do we need to use reference / pointer when same work can done by creating object of class?
Without a pointer or reference, you cannot create a collection of objects that have some commonality, but different in some specific sense. This is circumvented in some strict OOP languages like Java, C#, etc. by making all objects derive from a base class called Object
. C++ is a multi-paradigm language and the programmer is free to make such decisions as appropriate to his/her project. A way to do it in C++ is via pointers of the base class. This idiom is called run-time polymorphism.
for (const auto &this_car : v)
this_car->drive();
Here irrespective of the actual make, the vector v
will be able to hold the car, as long as the base class car
is part of the type. Likewise, drive
will be different for each make, but that isn't required to be known for the function which calls it.
EDIT:
Thanks to nijansen for pointing out that this post doesn't actually answer the question: why pointers or references (dynamic types) are required for run-time polymorphism? it only says they've to used to achieve it but doesn't explain why can't we use ordinary (static type) variables.
C++ is designed in such a way that an object's type may or may not be known completely at compile-time with just the type in hand. In Circle c;
we know c
is of type Circle
; whereas in Shape *p = make_shape();
we really do not know what object p
is pointing to; p
's own type is Shape*
but its pointed-to object's concrete type is unknown. All we know is that it is pointing to some object which derives from Shape
. Please do not confuse yourself with dynamic or automatic memory allocation; this is the same for automatic variables too E.g. Shape *p = &c;
. Here too p
in isolation the compiler doesn't know what concrete type the object is of, which p
is pointing to.
Had we written p
as a static (non-pointer, non-reference) type Shape p = make_shape();
or Shape p = c;
what really happens in slicing i.e. p
will be of the concrete type Shape
and since it's not a pointer, it'll copy (Shape) part of Circle
object c
to it, which is mostly undesirable.
Without knowing the underlying type, how do we call the right concrete type's functions? C++ provides virtual functions to do the job. This is why runtime polymorphism is always explained with virtual methods in C++; while in languages like Java and C# all methods are virtual and all object types are references/pointers. In a way the answer to your question is, the language is designed such that one needs reference/pointer variables for runtime polymorphism.