Default parameter in inherited virtual function

Hi,

Does the following code make sense?

class Base
{
protected:
virtual void func (bool state = true);
};

class Derived : public Base
{
protected:
virtual void func (bool state = true);
};

In the case above, I'm not redefining the virtual function's default parameter right? I'm redefining it if state=false?


what if it is the following:

class Derived : public Base
{
protected:
virtual void func (bool state);
};

Thank you.
Default parameters are a shortcut. They do not really change the functionality of virtual functions.

Even if Derived and Base have different default params -- say if Base defaults to true and Derived defaults to false -- everything would still work, and you'd be deriving the same function.

Which default parameter gets used depends on how the function is invoked.

Here is a test program which illustrates:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class Base
{
public:
    virtual void Func(bool state = true)
    {
        std::cout << "Base called: " << std::boolalpha << state << "\n";
    }
};

class Derived : public Base
{
public:
    virtual void Func(bool state = false)
    {
        std::cout << "Derived called: " << std::boolalpha << state << "\n";
    }
};


int main()
{
    Derived d;
    d.Func();       // "Derived called: false"
                    // Derived::Func is called, and Derived::Func's default
                    //  param is used because 'd' is of type Derived

    Base* b = &d;
    b->Func();      // "Derived called: true"
                    // Derived::Func is called (because it's virtual)
                    //  but Base::Func's default param is used because 'b'
                    //  is of type Base*.  To the compiler, 'b' might not
                    //  be a Derived.  That distiction is made at runtime.

    return 0;
}


Changing the default param doesn't stop polymorphism from occuring. The called function is determined at runtime, whereas the default param is determined at compile time.

Of course -- this is usually a terrible idea. If you're using default params in virtual functions, you typically should keep them all consistent to avoid confusion and complications.


EDIT -- as for your second question:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class NoDefault : public Base
{
public:
    virtual void Func(bool state)
    {
        std::cout << "NoDefault called: " << std::boolalpha << state << "\n";
    }
};

//...

NoDefault n;
n.Func();        // compiler error -- 'n' is a NoDefault object, and NoDefault::Func has no default.

Base* nb = &n;
nb->Func();   // state==true 
Last edited on
Thanks for the clarification.

I'm doing unit cpp test for my codes. There is such a rule "Do not overload an inherited virtual non-operator functions or default parameter value". And it flags out a violation at the function declaration in my Derived class, which I do not understand why if the function is exactly the same as the one in Base class.

However, it does not flag out an violation if I remove the default parameter in the Derived class function. But this will affect my subsequent function calls, as previously I need not pass in parameter explicitly.

As for the 2nd case, yes, I know I will need to pass in the parameter explicitly.

Any idea why a violation is flagged out?

Thank you.
flagged violations? Are you referring to compiler errors?

I don't know why it would error. Bad practice aside, I don't think there's a rule that prevents you from changing the default parameter in derived classes.

What compiler are you using?
Nope, not compilation error. The unit testing flags out that for the derived class function, it has violated the rule "Do not overload an inherited virtual non-operator functions or default parameter value", which implies my derived class has changed the default parameter?
I don't understand.

Can you show me a small bit of code and where the unexpected behavior is occuring?
I doing parasoft unit testing and got reply from that then the rule indeed has a bug. It's alright then.

Thank you.
Topic archived. No new replies allowed.