【问题标题】:C++ runtime polymorphism - regarding default parameter [duplicate]C ++运行时多态性-关于默认参数[重复]
【发布时间】:2015-10-04 17:08:19
【问题描述】:

我正在尝试在 C++ 中使用运行时多态性。有人可以解释一下这个程序的输出吗?我运行它,它给了我一个 Derived 的输出(意思是调用了派生类的函数 f())。

另外,如果我取消注释语句,程序的预期行为是什么 - d.f(); ?

// Example program
#include <iostream>
#include <string>

class Base {
    public :virtual void f(int a = 7){std::cout << "Base" <<std::endl;}
};
class Derived : public Base {
    public :virtual void f(int a) {std::cout << "Derived" <<std::endl;}
};

int main() {
    Derived d;
    Base& b = d;
    b.f();
    //d.f();

    return 0;
}

【问题讨论】:

  • 如果您想确保您的Derived::f() 在您的Base::f() 上按预期工作,您可以在函数声明之后使用关键字override,然后再执行它:virtual void f( int a ) override { std::cout &lt;&lt; "Derived" &lt;&lt; std::endl; } 这将确保将调用预期派生的正确函数以提供所需的实现。

标签: c++ polymorphism


【解决方案1】:

默认参数在编译时解析。所以对于编译器,你正在做b.f(7);

由于f是虚的,而实际的b是Derived,所以在运行时调用了derived的f(),因为运行时会在对象的vTable中查找,会找到Derived的f()。

另外,如果我取消注释,程序的预期行为是什么 声明 - d.f(); ?

我预计会出现编译器错误,因为编译器会查找 Derived::f 并且那里没有默认参数。

【讨论】:

  • d.f()上确实有编译错误。
  • @CaptainGiraffe 感谢您的确认,我没有尝试过 :)
  • @A.S.H: 派生类函数 f() 不期望有参数时怎么带参数?
  • @AshwinVenkataraman 答案是按顺序排列的。首先,编译器找到一个调用 f() 的 Base& 变量,因此它生成默认参数。然后,它发现 f() 是虚拟的,因此它设置代码以通过 vtable 查找重定向调用。由于 f 实际上是一个 Derived,它的 vtable 将指向一个 Derived 实现,因此调度程序将调用 Derived 实现
【解决方案2】:

当您在对象上调用函数时,必须在编译时找到该函数。在运行时,实际调用的函数取决于运行时分派机制。

在你的情况下,调用

b.f();

在编译时解析为 Base::f(int),并将 a 的值设置为参数的默认值。

电话

d.f();

将无法编译。该函数被解析为Derived::f(int)。但是由于Derived::f(int)没有参数的默认值,所以调用时必须提供值。

d.f(10);

会起作用的。

在运行时,该调用解析为Derived::f(int),因为没有其他实现覆盖它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 2018-06-30
    • 2014-02-10
    • 2021-04-08
    • 2010-10-01
    • 1970-01-01
    • 2014-01-05
    相关资源
    最近更新 更多