我能够调用一个没有在c ++中传递所需参数的方法。怎么会?

时间:2013-09-27 05:02:06

标签: c++ c++11

这是代码......

#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;
}

当使用Display()第二次调用bp方法时,令人惊讶的是它触及了Derived类中的方法。在Derived类中,我没有指定默认参数。但它采用了默认的基类参数。怎么样?

1 个答案:

答案 0 :(得分:21)

这让很多人感到惊讶,但默认参数是(或参数是,如果你指定了多个)基于静态类型(指针指向的类型)而不是动态类型(它当前碰巧指向的对象类型。)

因此,由于您使用Base *bp,因此使用Base中声明的默认参数,无论bp恰好指向BaseDerived

如果你关心它的原因:至少在典型的实现中,默认参数实际上是在编译时完全处理的。编译器看到您在没有提供参数的情况下调用了Display,并且Display有一个参数具有默认值。因此,当它为该调用生成代码时,将生成代码以传递指定的默认值。那时,它甚至无法猜测指针在调用发生时是否指向某些派生类型,因此所能做的就是根据静态类型生成代码。虽然这不是这种情况,但是当它生成执行调用的代码时,它甚至可能在尚未设计或编写的派生类上运行,因此使用该派生类中指定的值是不可能的。