The following is the code snippet from geeksforgeeks to demonestrate early and late binding in C .
// CPP Program to illustrate late binding
#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() { cout<<" In Base \n"; }
};
class Derived: public Base
{
public:
void show() { cout<<"In Derived \n"; }
};
int main(void)
{
Base *bp = new Derived;
bp->show(); // RUN-TIME POLYMORPHISM
return 0;
}
We need to use the virtual
keyword inorder to get polymorphism in C . However if I remove the virtual
keyword from the class Base and use auto
keyword when I create an object(auto *bp = new Derived;
) still get same result. How is it possible as auto variable is resolved at compile time?
CodePudding user response:
No, it does not. auto
is deduced completely at compile-time, the same way as template arguments are.
So here new Derived
has type Derived*
and therefore the obvious type for auto
be deduced to is Derived
.
auto *bp = new Derived;
is here completely equivalent to
Derived *bp = new Derived;
and you can see that the "correct" show
is called here only because the pointer is already a pointer to the derived class.
If you use static_cast<Base*>(bp)->show()
to cast the pointer back to its base class first, then you will see that there is no runtime polymorphism without virtual
.
CodePudding user response:
No, the auto
keyword does not mean that anything is resolved at run time. It's just a shorthand that tells the compiler to figure out what type should be put there.
When you write auto * bg = new Derived;
is means the same thing as Derived * bg = new Derived;
. If you don't believe me, look at the error message your compiler gives you when you run this code:
class Base {};
class Derived: public Base {};
int main(void)
{
auto * bp = new Derived;
int i = bp; // the error here tells us what type bp is
}
The error message for the invalid definition of i
will be something like invalid conversion from 'Derived*' to 'int'
. This tells us that the compiler figured out that auto
is actually Derived
, and it did it at compile time, not run time.
Moving on, to answer the second part of your question: you were wondering why bp->show()
resolved to Derived::show
instead of Base::show
when you removed the virtual
keyword. The answer is simple: the compiler knows that the type of bp
is Derived *
, so when you try to call show
, it will find Derived::show
and use that. There is nothing magical or mysterious going on there.
Now, if you want to cast bp
to a pointer of type Base *
and then call show()
on that pointer, that is the case where you have use virtual functions if you want your program to use Derived::show
instead of Base::show
.