13

Here is the code...

#include "stdafx.h"
#include<iostream>
using namespace std;

class Base
{
public:
    virtual void Display(bool b = false)
    {
        cout<<"Base"<<"\t"<<b<<endl;
    }
};

class Derived : public Base
{
public:
    virtual void Display(bool b) override
    {
        cout<<"Derived"<<"\t"<<b<<endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    Base* bp = new Base();
    Derived* dp = new Derived();
    bp->Display();
    dp->Display(true);
    bp = new Derived();
    bp->Display();
    cout<<"Done"<<endl;
    return 0;
}

When the Display() method called second time using bp, surprisingly it hit the method in Derived class. in Derived class I didn't specify default argument. But it took the default base class argument. How?

4

1 回答 1

21

This surprises quite a few people, but the default argument is (or arguments are, if you've specified more than one) based on the static type (the type the pointer is declared to point at) not the dynamic type (the type of object to which it currently happens to point).

As such, since you're using Base *bp, the default arguments declared in Base are used, regardless of whether bp happens to be pointing to a Base or a Derived.

In case you care about why this is: at least in the typical implementation default arguments are actually handled entirely at compile time. The compiler sees that you've called a Display without supplying an argument, and that Display has one argument with a default value. Therefore, when it's generating code for that call, the code is generated to pass the default value that was specified. At that time, it has no way of even guessing whether the pointer may point at some derived type when the call takes place, so all it can do is generate code based on the static type. Though it isn't the case here, when it generates the code to do the call, it's even possible that it could be operating on a derived class that hasn't been designed or written yet, so using a value specified in that derived class wouldn't be possible.

于 2013-09-27T05:07:31.627 回答