header.h
#include <iostream>
using namespace std;
class A
{
public:
virtual void display(int i=5) { cout<< "Base::" << i << endl; }
};
class B : public A
{
public:
void display(int i=9) { cout<< "Derived::" << i << endl; }
};
source.h
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
A * a = new B();
a->display();
A* aa = new A();
aa->display();
B* bb = new B();
bb->display();
}
output
Derived::5
Base::5
Derived::9
My understanding was default parameter functions were resolved during compile time using function overloading. Virtual functions were then resolved during runtime using function overriding.
But what is happening is a mess.
How does the function resolution actually happen here?
Default Arguments are the values provided during function declaration, such that values can be automatically assigned if no argument is passed to them. In case any value is passed the default value is overridden and it becomes a parameterized argument.
Yes, C++ virtual functions can have default parameters.
Default arguments are only allowed in the parameter lists of function declarations and lambda-expressions, (since C++11) and are not allowed in the declarations of pointers to functions, references to functions, or in typedef declarations.
Constructors cannot have default parameters.
Your code is actually seen by the compiler like this:
(The display()
method is not actually there, but the resolving works in similar way)
class A
{
public:
virtual void display(int i) { cout<< "Base::" << i << endl; }
void display() { display(5); }
};
class B : public A
{
public:
void display(int i) override { cout<< "Derived::" << i << endl; }
void display() { display(9); }
};
Now you should understand what happens. You are calling the non-virtual display()
which calls the virtual function. In more strict words: the default argument is resolved just like if the no-arg non-virtual method was there - by the type of the variable (not by the actual type of the object), but the code gets executed according to real object type, because it is virtual method:
int main()
{
A * a = new B(); // type of a is A* real type is B
a->display(); // calls A::display() which calls B::display(5)
A* aa = new A(); // type of aa is A* real type is A
aa->display(); // calls A::display() which calls A::display(5)
B* bb = new B(); // type of bb is B* real type is B
bb->display(); // calls B::display() which calls B::display(9)
}
There is no polymorphism on default arguments. They are resolved compile-time.
A::display
has default argument equal 5.
B::display
has default argument equal 9.
It's only the type of a
, aa
, bb
variables that matters.
Use of different default arguments in polymorphic methods is confusing and should be avoided.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With