这是代码......
#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
类中,我没有指定默认参数。但它采用了默认的基类参数。怎么样?
答案 0 :(得分:21)
这让很多人感到惊讶,但默认参数是(或参数是,如果你指定了多个)基于静态类型(指针指向的类型)而不是动态类型(它当前碰巧指向的对象类型。)
因此,由于您使用Base *bp
,因此使用Base
中声明的默认参数,无论bp
恰好指向Base
或Derived
。
如果你关心它的原因:至少在典型的实现中,默认参数实际上是在编译时完全处理的。编译器看到您在没有提供参数的情况下调用了Display
,并且Display
有一个参数具有默认值。因此,当它为该调用生成代码时,将生成代码以传递指定的默认值。那时,它甚至无法猜测指针在调用发生时是否指向某些派生类型,因此所能做的就是根据静态类型生成代码。虽然这不是这种情况,但是当它生成执行调用的代码时,它甚至可能在尚未设计或编写的派生类上运行,因此使用该派生类中指定的值是不可能的。