【问题标题】:Hide virtual function with non-virtual override使用非虚拟覆盖隐藏虚拟功能
【发布时间】:2014-06-18 12:55:11
【问题描述】:

拥有

#include <iostream>

using namespace std;

class A {
public:
    virtual void foo() {
        cout << "A" << endl;
    }
};

class B : public A {
public:
    void foo() {
        cout << "B" << endl;
    }
};

class C : public B {
public:
    void foo() {
        cout << "C" << endl;
    }
};

int main() {
    C c;
    B* b = &c;
    b->foo();

    return 0;
}

输出是C,但我期望的是B

我没有用virtual 修饰符声明B::foo(),所以我希望函数调用由静态类型确定(无多态性)。

为什么会调用C::foo()

是否可以在派生类中提供非虚函数,将虚函数隐藏在基类中?派生成员函数应该有什么签名以便b-&gt;foo() 调用它,而不是(b-&gt;*&amp;A::foo)()

【问题讨论】:

  • B::foo() 虚拟的。你问题的前提是错误的。
  • virtual 继承自 A。您不需要重新指定它(尽管为了清楚起见我建议您这样做)。
  • @我已经给你的问题一个更准确的标题。这是一个合理的问题,可以得到一个很好的答案。既然您知道了这个问题,为什么不编辑您的问题以符合现实,以便其他人可以从一个好的解释中受益? (即“我没有将B::foo() 声明为虚拟”而不是“B::foo()` 不是虚拟的”)
  • 我建议不要将virtual标记为B::foo,而是标记override
  • 实际上,我为您进行了我正在考虑的编辑。我希望这能保留您问题的本质,同时不再假设与现实相反的“事实”。

标签: c++ inheritance polymorphism overriding virtual-functions


【解决方案1】:

成员函数的虚继承原理是C++标准的直接结果:

10.3/2:如果在 Base 类和 Derived 类中声明了虚成员函数 vf,则 直接或间接从 Base 派生, 同名的成员函数 vf , parameter-type-list , cv-qualification 和 refqualifier(或没有相同)作为 Base::vf 是 声明,然后 Derived::vf 也是虚拟的

因此,无论继承级别如何,该函数在从 A 派生的所有类中都是虚拟的。不需要放置关键字virtual

这种多态方法的目标是确保您始终调用与对象的真实身份相对应的适当函数,无论您使用的是指向基类的指针还是指向对象真实类的指针。这就是你获得“C”的原因!

this related SO question 中,我解释了一个技巧,给人一种使用多重继承在一个层次上移除虚拟性的印象。然而,它只能为一个级别完成(你应该为你的基指针的类做)。

*顺便说一句,你可以写pb-&gt;B::foo();,不需要*&amp;

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2020-06-05
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多