为什么 class B 中的 f2 被 class D 中的 f2 覆盖

Why f2 in class B is overridden by f2 in class D

我无法理解孙子 (D) 如何覆盖隐藏的(通过 C::f2(A&) 方法 (B::f2(A))。

这是一个示例代码:

class B{
    public:
    virtual void f2(A a){cout<<"B::f2()"<<endl;}
};

class C:public B{
private:
    public:
    virtual void f2(A& a){cout<<"C::f2(A&)"<<endl;
    }

};

class D:public C{
    public:
    void f2(A a){cout<<"D::f2(A)"<<endl;}
};

int main(void)
{
    B* b = new D();
    A a2 = A();
    A &a = a2;
    b->f2(a); // prints D::f2 - should'nt it print B::f2??

    C* c = new D();
    c->f2(a); // prints C::f2 - as expected
    return 0;

}

B的接口没有f2( A& ),所以如果编译器不进行隐式转换,你的b->f2( a );将无法编译。

但是由于 B 的接口确实有 f2( A ),编译器隐式转换 (*1) 你的 a 从类型 A& 到类型 A.所以,f2( A )形式的函数是从B.

的接口中选取的

并且由于您的 D 覆盖了该函数,因此 D 的函数最终被调用。

(*1) C++ die-hards 可能知道比 'implicitly converts' 更具体的术语,以准确说明在这些情况下发生的情况。但我只是一个业余爱好者。

Why f2 in class B is overridden by f2 in class D

因为D::f2有相同的参数列表。如果 base 中存在这样的虚函数,则具有相同名称和参数列表的函数将覆盖 base 中的虚函数。

虚函数是否被中间库中的另一个同名函数隐藏对此没有影响。

来自标准(草案)的规则:

[class.virtual]

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 ([dcl.fct]), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf overrides Base::vf.

因此,总而言之,D::f2 覆盖了 B::f2,因为它具有相同的参数列表。它不会覆盖 C::f2,因为参数列表不同。