0

The answer to the below output of main is "derived class display with i=10", but I do not understand why? Surely the function was invoked on the base type?

What is the thought-process in determining the answer here?

class base
{
  public:
         virtual void display(int i = 10)
         {
           cout<<"Base class display with i = "<<i<<endl;
         }

};

class derived : public base
{
  public:
          void display(int i = 20)
         {
           cout<<"Derived class display with i = "<< i <<endl;
         }

};

int main(int argc, char *argv[])
{
     base *bptr = new derived;
     bptr->display();

      return 0;
}
user997112
  • 29,025
  • 43
  • 182
  • 361

1 Answers1

2

Have a look at Can virtual functions have default parameters?:

A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides.

Therefore, bptr->display(); calls the derived version of display, but uses the argument from base, the static type of the pointer bptr.

This is because the default value of an argument has to be determined at compile time while dynamic binding is deferred to the runtime. Using different default arguments in the base and derived versions of the same virtual is almost guaranteed to cause trouble. Problems are likely to arise when the virtual is called through a reference or pointer to base, but the version that is executed is the one defined by the derived. In such cases, the default argument defined for the base version of the virtual will be passed to the derived version, which was defined using a different default argument.

Community
  • 1
  • 1
Yang
  • 7,712
  • 9
  • 48
  • 65
  • Ok so the only way you can use the default arguments for the virtual function are if you declare the static type to be the derived class? Derived d = new Derived(); – user997112 Aug 05 '13 at 20:18
  • @user997112 You'd better use the same default arguments to avoid any surprises. – Yang Aug 05 '13 at 20:19
  • what is the reason for this behaviour, just so I can understand- rather than memorise this rule? Are there any other similar rules for derived classes? – user997112 Aug 05 '13 at 20:21
  • @user997112 The essential reason for this behavior is that default argument check has to be performed at compile time, but dynamic binding is deferred to runtime. The best practice is to avoid different default arguments of virtual functions. – Yang Aug 05 '13 at 20:28
  • Excellent explanation- just a small nit-picky question- why does default argument-checking have to happen at compile time? – user997112 Aug 05 '13 at 20:42
  • 1
    @user997112 If we don't supply an argument, the compiler needs to insert the default value to generate code. This is done at compile time. – Yang Aug 05 '13 at 21:00