我无法理解孙子(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被D类中的f2覆盖


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

虚拟功能是否已被中间库中同名的另一个功能隐藏,对此没有影响。

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


  [class.virtual]
  
  如果在类vf和类Base中声明了虚拟成员函数Derived,这些成员函数直接或间接从Base派生,则成员函数vf具有相同的名称,parameter-type-list( [dcl.fct]),cv限定符和ref限定符(或没有ref限定符)声明为Base::vf,然后Derived::vf会覆盖Base::vf


因此,总结来说,D::f2会覆盖B::f2,因为它具有相同的参数列表。它不会覆盖C::f2,因为参数列表不同。

09-30 15:37
查看更多