C ++中的虚函数层次结构

virtual function hierarchy in c++

我对 C++ 中的虚函数主题有点困惑。 是否有总结所有可能情况的流程图?

例如:

    class A {
       public:
          virtual void f(const int i) { cout << "A::f" << endl; }
    };

    class B : public A {
       public:
          // Hide A's f with new implementations
          void f() { cout << "B::f" << endl; }
    };

    class C : public B {
       public:
          void f() { cout << "C::f" << endl; }
    };
class D : public B { public:
    void f(const int i) { cout << "D::f" << endl; }
};


    void main() {
       D d;
       C c;
       B* pb = &c;
       pb->f();
       A* pa = &d;
       A* paa = &c;
       pa->f(1);
       paa->f(1); //in here C::f would be invoked?
    }

在这种情况下,B 隐藏了 A::f,并且 C 覆盖了具有相同签名的 B::f

pb->f() 会调用 C::f 吗? pa->f(1) 会调用 A::f 吗?

我问它是否 B::f 仍然被认为是虚拟的,所以它的导数 类 可以覆盖它,尽管它隐藏了 A::f.

以及如果 C::f 默认被认为是虚拟的?

Would pb->f() invoke C::f?

不,不会。

I ask it to know if B::f is still considered virtual so its derivative classes can override it, though it hides A::f.

B::f() 不是 virtual 成员函数。

要使 B::f() 成为虚拟成员函数,您必须使用:

class B : public A {
   public:
      // Hide A's f with new implementations
      virtual void f() { cout << "B::f" << endl; }
};

更新

您用以下附加问题更新了 post:

Would pa->f(1) invoke A::f?

是的,会的。通过pa看,B::f()C::f()都不存在,只有A::f(int)存在。

A::fB::f 是两个不同的函数,尽管它们具有相同的名称;因为 B::f 没有声明为 virtual 只有 A::f 是虚拟的 - 没有人覆盖它。

pb->f()利用指针的静态类型,也就是B*,来决定调用哪个函数;那将是 B::f.

Is there a flowchart that summarize all possible cases?

总的来说,您需要了解 C++ 中的整套名称查找规则,不幸的是,这非常复杂。

假设您只想知道什么覆盖什么,您可以在标准的几段中找到所有详细信息。

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 (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

...

Even though destructors are not inherited, a destructor in a derived class overrides a base class destructor declared virtual; see 12.4 and 12.5.

...

The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. If a function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:

  • both are pointers to classes, both are lvalue references to classes, or both are rvalue references to classes
  • the class in the return type of B::f is the same class as the class in the return type of D::f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::f
  • both pointers or references have the same cv-qualification and the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.

因为B::fA::f没有相同的参数类型,所以B::f不会覆盖A::f,同理,C::f不会覆盖 A::f。由于 B::f 未声明 [​​=31=] 它不会覆盖 A::fB::f 不是虚拟的。 C::f 不会覆盖 B::f 因为 B::f 不是虚拟的。

由于 B::f 不是虚函数,pb->f() 总是调用 B::f 而不是派生的 class.[=45= 中任何名为 f 的函数]

B::f not 覆盖 A::f 因为它们没有相同的参数类型列表,因此它也不是虚拟的,[class.virtual]/p2:

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 (8.3.5), cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.

因此派生的 class 方法可以是隐式虚拟的,无论它是否具有 virtual 说明符,只要它匹配基本 class 方法的某些属性。在这种情况下 B::f 不是虚拟的,因此 pb->f() 使用指针的静态类型 B*,并调用 B::f 而不是 C::f.