关于c ++:使用非虚拟覆盖隐藏虚拟功能

Hide virtual function with non-virtual override

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#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->foo()调用它,而不是(b->*&A::foo)()


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

10.3/2: If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base,
a member function vf with the same name, parameter-type-list ,
cv-qualification, and refqualifier (or absence of same) as Base::vf is
declared, then Derived::vf is also virtual.

因此,不管继承的级别如何,函数在以某种方式从a派生的所有类中都是虚拟的。不需要放置关键字virtual

这种多态方法的目标是确保始终调用与对象的真实意念相对应的适当函数,而不管使用指向基的指针或指向对象真实类的指针。这就是为什么你得到"C"!

在这个相关的问题中,我解释了一个技巧,用多重继承在一个层次上消除虚拟性。但是,它只能在一个级别上完成(应该在基指针的类上完成)。

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