当中间 类 跳过实现时,在继承层次结构中执行哪个虚方法?

Which virtual method is executed in an inheritance hierarchy when intermediate classes skip the implementation?

我确定之前有人问过这个问题,但我只是不知道要搜索什么。因此,一旦有人向我指出类似问题,我很乐意删除此问题。如果有人有更好的建议,我也很乐意重命名问题:-)

我想知道以下代码是否是标准定义的行为,或者这是否可能 compiler/platform 依赖:

struct A
{
    virtual void f()
    {
        std::cout << "A::f()" << std::endl;
    }
};

struct B : public A
{
    // f() is not implemented here
};

struct C : public B
{
    virtual void f() override
    {
        B::f(); // call f() of direct base class although it is not implemented there
        std::cout << "C::f()" << std::endl;
    }
};

int main()
{
    A* pA = new C();
    pA->f();
}

Visual Studio 2017 和 gcc 5.4.0 的输出是:

A::f()
C::f()

编译器是否会在层次结构中向上搜索直到找到实现?你能link达到C++标准吗?我通过在纯虚拟中制作 f() 来测试它, linker 很好地告诉我有一个未解析的符号。我可以依靠它吗?

据我所知,使用像 B::f() 这样的范围运算符总是调用非虚拟版本。所以永远不会发生多态性,是吗?

编辑:误导的打印语句,将 "B::f()" 替换为 "C::f()"。

指针的动态类型

A* pA = new C();

C *

所以调用了classC中的虚函数

struct C : public B
{
    virtual void f() override
    {
        B::f(); // call f() of direct base class although it is not implemented there
        std::cout << "B::f()" << std::endl;
    }
};

classB并没有重新定义基classA的虚函数。所以在这个语句中

        B::f(); // call f() of direct base class although it is not implemented there

调用了classA中定义的虚函数。即table的虚函数指针classB包含了classA中定义的函数的地址。

在本次通话中

B::f();

可以访问 class B 的虚函数 table 并且这个 table 包含 class A 中函数定义的地址,因为class B.

中的函数未被覆盖

来自 C++ 标准(5.2.2 函数调用)

  1. ...If the selected function is non-virtual, or if the id-expression in the class member access expression is a qualified-id, that function is called. Otherwise, its final overrider (10.3) in the dynamic type of the object expression is called; such a call is referred to as a virtual function call. [