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

Sun*_*VLN 13 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;
}
Run Code Online (Sandbox Code Playgroud)

Display()第二次使用该方法时bp,令人惊讶的是它在Derived课堂上遇到了这个方法.在Derived类I中没有指定默认参数.但它采用了默认的基类参数.怎么样?

Jer*_*fin 21

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

因此,既然您正在使用Base *bp,Base则使用声明的默认参数,无论是否bp恰好指向a Base或a Derived.

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