0
#include<iostream>
using namespace std;

class Base
{
public:
    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;
}

In the above code, show() is declared in the base class and is overriden in the derived class. The base class pointer bp points to a derived class object. Now, when bp to call the non virtual show() function.

Output:

In Base

But, bp points to derived class, so why the base's function is called rather than the derived class function?

StoryTeller - Unslander Monica
  • 148,497
  • 21
  • 320
  • 399
Jayesh
  • 4,303
  • 4
  • 25
  • 56
  • Recommended reading: [When to use virtual destructors?](https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors) – user4581301 Aug 01 '18 at 05:49

8 Answers8

4

// RUN-TIME POLYMORPHISM

In C++ it's opt-in. For a function call to be resolved polymorphically at run-time, the programmer must explicitly say that's desired by marking it virtual.

The reason is that dynamic dispatch is never without a cost, and a staple of C++'s design is that "you don't pay for what you don't need". You must say you really need it for it to be enabled.

StoryTeller - Unslander Monica
  • 148,497
  • 21
  • 320
  • 399
2

You need to make show() virtual to allow kicking in of runtime polymorphism.

virtual void show() { cout<<" In Base \n"; }
Gaurav Sehgal
  • 7,011
  • 2
  • 15
  • 29
  • I know, but base pointer point to derived then why call base function? – Jayesh Aug 01 '18 at 05:31
  • 2
    @Jayesh Because if the function is not `virtual`, C++ does not generate the code for a `Base` to invoke `Derived`'s override. There is a small performance hit using runtime polymorphism, and C++ has a policy of not making a program pay more than the programmer asked for. – user4581301 Aug 01 '18 at 05:33
  • @Jayesh Without `virtual` the binding of `show()` and its body is not delayed, hence no polymorphism. – Gaurav Sehgal Aug 01 '18 at 05:33
  • 1
    Additional fun fact: When you declare a function to be `virtual`, all overrides of that function in derived classes are `virtual` unless `final` is invoked. Also look into and get used to using the `override` keyword. It's very handy in catching mistakes like this. – user4581301 Aug 01 '18 at 05:39
  • @Jayesh ,without the keyword "Virtual " Vptr and Vtable never got created ,the binding to the constructor of child class never happened ,hence it remains with the base class. – Nihar Aug 01 '18 at 05:47
2

To complement the other answers posted here, with reference to this comment:

I know, but base pointer point to derived then why call base function?

Please see this post: https://stackoverflow.com/a/50830338/5743288

It follows, therefore, that if you were to do this:

Derived *dp = new Derived;
dp->show();

You would get the following output:

In Derived

even without declaring show() as virtual (because the compiler would then know which method you have said that you want to call).

So, as others point out, if you want the service you have to pay the price (although, even with your original code, the compiler would probably be smart enough to optimise out the virtual function call anyway, see here).

Paul Sanders
  • 15,937
  • 4
  • 18
  • 36
1

Most folks have already answered that you need to declare a function to be virtual for it to bind at runtime when your code executes. I want to add that without virtual, the method to be called is decided at compile time and it will pick the method of the class whose variable/pointer type you declared. In your case, Base class type.

Additionally, would like to provide a good to read link which can help clear your concept of runtime polymorphism in C++ : https://www.geeksforgeeks.org/virtual-function-cpp/

Viral Modi
  • 1,267
  • 5
  • 15
1

The core issue here is that show method is not overridden in the derived class. Starting with C++11 you can use override specifier to ensure that method really does override something so compiler will detect this problem for your:

class Derived: public Base
{
public:
    void show() override { cout<<"In Derived \n"; }
};

prog.cc:13:10: error: 'void Derived::show()' marked 'override', but does not override

In order to override a method it should be declared as virtual in base class:

class Base
{
    public: virtual
    void show() { cout<<" In Base \n"; }
};
user7860670
  • 32,142
  • 4
  • 44
  • 75
0

This is actually what is call RUN TIME POLYMORPHISM. And in C++ its programmers discretion to call desired function of base or derived class, based on the object given to base class pointer.

Irrespective of the base class pointer pointing to any derived class object. If the function being called is non-virtual then always base class function will be called to a base class pointer.

To call derived class function from a base class pointer the function must be marked as virtual.

Rizwan
  • 1,884
  • 1
  • 7
  • 23
0
int main(void)
{
    Base *bp = new Derived;
    bp->show(); // RUN-TIME POLYMORPHISM
    return 0;
}

compiler bind it with base class object while compiling "new Derived" passing object to base but it been binded with base object it refer to same class once if you add virtual binding will happen run time and once object passed by derived it bind with drived class

Subodh
  • 40
  • 5
0

In c++,even-though you make the base class pointer point to derived class object, it still calls the function from the base class, this is because of Early binding, so in order to achieve Late binding make the function inside the base class as virtual. i.e., virtual void show() { ....... }
Now, the o/p will be "In Derived".