Could anybody explain where c++ compilers keep default values for parameters for virtual functions? I know it is a bad idea to change these parameters in child classes but why? Thanks.
2 Answers
It's a bad idea because they aren't kept anywhere.
The default values that are used will be those defined in the static (compile-time) type. So if you were to change the default parameters in an override, but you called the function through a base class pointer or reference, the default values in the base would be used.
#include <iostream>
struct Base
{
virtual ~Base(){ }
virtual void foo(int a=0) { std::cout << "base: " << a << std::endl; }
};
struct Derived : public Base
{
virtual ~Derived() { }
virtual void foo(int a=1) { std::cout << "derived: " << a << std::endl; }
};
int main()
{
Base* derived = new Derived();
derived->foo(); // prints "derived: 0"
delete derived;
}

- 7,605
- 4
- 40
- 55
-
9To understand how it works, the default value is filled in at the call site (where only the static type is known) so the compiler actually translate `derived->foo()` into `derived->foo(0)` at compile time. – Matthieu M. Aug 07 '13 at 15:11
Giving virtual functions default argument initializers tends to defeat polymorphism and introduce unnecessary complexity into a class hierarchy.
consider the following non compliant code
class Thing {
public:
virtual ~Thing();
virtual void doItNTimes( int numTimes = 10 );
virtual void doItThisHigh( double howHigh = 1.0 );
// ...
};
class MyThing : public Thing {
public:
void doItNTimes( int numTimes );
void doItThisHigh( double howHigh = 2.2 );
// ...
};
A default initializer is not part of the type of a function signature and does not participate in overriding or hiding. Therefore both of the base class virtual functions shown in this Non-Compliant Code Example are overridden in the derived class. However, the differences in the status of default argument initializers in the base class and derived class interfaces causes differences in behavior depending on which interface is used to access an object.
MyThing *mt = new MyThing;
Thing *t = mt;
t->doItNTimes(); // default of 10
mt->doItNTimes(); // compile time error!
t->doItThisHigh(); // default of 1.0!
mt->doItThisHigh(); // default of 2.2
In this piece of code, the intention of the designer of the MyThing class is not clear. Presumably, it is important that the default value to doItThisHigh for an object of type MyThing be 2.2. However, it is not clear whether that value should also be used by default when a MyThing is manipulated through its Thing interface.
For more details Please refer the below link https://www.securecoding.cert.org/confluence/display/cplusplus/OOP04-CPP.+Prefer+not+to+give+virtual+functions+default+argument+initializers

- 1,149
- 1
- 6
- 19