0

I do not understand the behavior of this code. Can someone explain how the 3rd call uses the default parameter of A::f() but the body of B::f() , because I was so surprised to see it and I still do not get how it happened.

#include <iostream>  
// C++98
using std::cout; using std::endl;

class A {
    public: virtual void f(int n=20) { 
        cout << "In A::f(20) with n = " << n << " and n+2 = ";
        cout << n+2; 
    }
    virtual ~A() {}
};

class B : public A {
    public: virtual void f(int n=30) {
        cout << "In B::f(30) with n = " << n << " and n-4 = ";
        cout << n-4;
    }
};


int main () 
{
    A* pa1 = new A;
    pa1->f(); cout << endl;  // outputs 22, expected, 20+2
    B* pb = new B;
    pb->f(); cout << endl;  // outputs 26, expected, 30-4
   
    A* pa = new B;
    pa->f(); cout << endl; // outputs 16 , 20-4 , NOT expected by me! 
    delete pa1; delete pb; delete pa;
}

The output of the code is :

In A::f(20) with n = 20 and n+2 = 22
In B::f(30) with n = 30 and n-4 = 26
In B::f(30) with n = 20 and n-4 = 16
  • 2
    When you do `pa->f()` it will use the declaration from the `A` class, but redirect the call to `B::f`. That means the default argument provided in `A::f` will be used. – Some programmer dude May 13 '23 at 18:53
  • To ensure that the first comment is correct, you can remove `=30` and see `pa->f()` still compiles. BTW prefer `override` suffix instead of `virtual` prefix in derived classes. – 273K May 13 '23 at 18:57
  • 1
    I do not understand why you would even want the mixing of virtual functions and default parameters. (I never needed it in almost 30 years of C++ dev). Just be explicit and pass the parameters at the call site (you could use `inline contexpr int some_constant = 10;` in a header file and use that). – Pepijn Kramer May 13 '23 at 20:39

0 Answers0