-1

I am trying to experiment with runtime polymorphism in C++. Can someone explain me the output of this program? I ran it and it gave me an output of Derived (meaning, the function f() of the derived class is called).

Also, what is the expected behaviour of the program if I uncomment the statement - d.f(); ?

// Example program
#include <iostream>
#include <string>

class Base {
    public :virtual void f(int a = 7){std::cout << "Base" <<std::endl;}
};
class Derived : public Base {
    public :virtual void f(int a) {std::cout << "Derived" <<std::endl;}
};

int main() {
    Derived d;
    Base& b = d;
    b.f();
    //d.f();

    return 0;
}
chrisrhyno2003
  • 3,906
  • 8
  • 53
  • 102
  • If you want to ensure that your `Derived::f()` works as expected over your `Base::f()` you can use the key word `override` after the function's declaration before its implementation as such: `virtual void f( int a ) override { std::cout << "Derived" << std::endl; }` This will ensure the correct function of an expected derived will be called to give you the implementation you want. – Francis Cugler Oct 04 '15 at 17:19

2 Answers2

1

The default parameter is resolved at compile time. so for the compiler, you are doing b.f(7);

Since f is virtual, and the actual b is a Derived, the f() of derived is called at runtime, because the runtime will look in the vTable of the object, and it will find f() of Derived.

Also, what is the expected behaviour of the program if I uncomment the statement - d.f(); ?

I expect a compiler error, because the compiler will lookup Derived::f and there is no default parameter there.

A.S.H
  • 29,101
  • 5
  • 23
  • 50
  • 1
    There is indeed a compile error on d.f(). – Captain Giraffe Oct 04 '15 at 17:19
  • @CaptainGiraffe thanks for confirming, I did not try it :) – A.S.H Oct 04 '15 at 17:20
  • @A.S.H: How is that the derived class function f() takes a parameter when it does not expect a parameter? – chrisrhyno2003 Oct 04 '15 at 17:23
  • @AshwinVenkataraman the answer is in the sequence of things going on. First, the compiler finds a Base& variable invoking f(), so it generates the default parameter. Then, it sees that f() is virtual, so it sets up code to redirect the call through the vtable lookup. Since f is actually a Derived, its vtable wil point a the Derived implementation, so the dispatcher will invoke the Derived implementation – A.S.H Oct 04 '15 at 17:25
0

When you call a function on an object, the function has to be found at compile time. At run time, the actual function that gets called depends on the run time dispatch mechanism.

In your case, the call

b.f();

gets resolved to Base::f(int) at compile time with value of a set to the default value of the argument.

The call

d.f();

will fail to compile. That function gets resolved to Derived::f(int). However, since Derived::f(int) does not have a default value of the parameter, a value must be provided when calling it.

d.f(10);

will work.

At run time, that call resolved to Derived::f(int), since there is no other implementation overrides it.

R Sahu
  • 204,454
  • 14
  • 159
  • 270