【问题标题】:What was it that made the compiler change from a dynamic call in the first example to a static call in the second? [duplicate]是什么使编译器从第一个示例中的动态调用更改为第二个示例中的静态调用? [复制]
【发布时间】:2014-05-19 20:02:13
【问题描述】:

这是我prior question 的延续。请注意,下面的代码在p->f(1.0) 打印Derived::f(double) 进行虚拟调用

#include <iostream>
#include <complex>
using namespace::std;

class Base
{
public:
    virtual void f(double);
    virtual ~Base() {};
};

void Base::f(double) { cout << "Base::f(double)\n"; }

class Derived : public Base {
public:
    void f(std::complex<double>);
    void f(double);
};

void Derived::f(std::complex<double>) { cout << "Derived::f(complex)\n"; }
void Derived::f(double) { cout << "Derived::f(double)\n"; }

int main()
{
    Derived* p = new Derived;
    p->f(1.0);
    delete p;
}

如果我只是消除Derived 中的成员函数void f(double);,代码会静态调用Derived::f(std::complex&lt;double&gt;)

是什么使编译器从第一个示例中的动态调用更改为第二个示例中的静态调用?我会很感激标准中的一些引用。

编辑:

正如我在上面所问的,对被认为是重复的问题的答案没有引用标准。谢谢。

【问题讨论】:

  • 您预计会发生其他事情吗?
  • 为什么每个人总是为这些例子写newdelete?!没必要……
  • @KerrekSB 也许这可以解释:stackoverflow.com/a/334752/5987
  • 我对您原始问题的回答也回答了这个问题。 :) 编辑:但没有引用标准。
  • 要求参考标准并不会使您的问题与众不同。如果您真的想要该参考资料,请在其他问题中添加一个赏金,说明它是赏金的原因,或者只是评论一个答案并要求它。

标签: c++ c++11 overloading overriding


【解决方案1】:

是什么使编译器从第一个示例中的动态调用更改为第二个示例中的静态调用?

查找规则。如果没有 f(double) 在派生中的声明(并且缺少使用声明),f(complex&lt;double&gt;) 隐藏 f(double) 在基础中。当编译器在Derived 中查找p-&gt;f(1.0) 时,会发现一个重载并给定一个选项使用它。它永远不会移动到Base 来检查是否存在不同的重载。

【讨论】:

  • 值得强调的是,这与虚拟多态性完全无关。这是类继承的一个简单属性。
  • 我的理解是,在这种情况下,Base 中的虚函数声明始终具有优先权。您能否提供标准的具体报价来支持您上面所说的内容?另一个被认为是重复的答案没有引用标准。
  • C++11 标准草案的 10.2 怎么样(重点是我的):“2. 以下步骤定义了在类范围 C 中查找成员名称 f 的结果... 4 . 如果 C 包含名称为 f 的声明,则声明集包含在 C 中声明的满足查找发生的语言构造要求的每个 f 声明... 如果结果声明集不为空,则子对象集包含 C 本身,计算完成。 5. 否则[查看基类]。”
猜你喜欢
  • 2016-10-14
  • 2020-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
相关资源
最近更新 更多