我不明白为什么编译代码片段的第二个版本。AFAIK 它不应该,因为 §10.3/2

I don't understand why the second version of the snippet compiles. AFAIK it shouldn't, because of §10.3/2

本文关键字:因为 不应该 AFAIK 编译 为什么 明白 代码 片段 版本 第二个      更新时间:2023-10-16

由于 §10.3/2,此代码无法编译,即虚函数A::fD中有多个最终覆盖器。

#include <iostream>
class A { public: virtual void f(){ std::cout << "A::f" << 'n'; } };
class B : public virtual A { public: void f(){ std::cout << "B::f" << 'n'; } };
class C : public virtual A { public: void f(){ std::cout << "C::f" << 'n'; } };
class D : public B, public C { };
int main()
{
    D d;
    d.f();
}

但与我的期望相反,这段代码编译。鉴于 §10.3/2 包含这句话,For convenience we say that any virtual function overrides itself ,在我看来,我们在这里遇到了上面提到的相同问题,即虚函数A::fD中有多个最终覆盖器,即A::fC::f。事实上,调用d.f()调用C::f。为什么?

#include <iostream>
class A { public: virtual void f(){ std::cout << "A::f" << 'n'; } };
class B : public virtual A {};
class C : public virtual A { public: void f(){ std::cout << "C::f" << 'n'; } };
class D : public B, public C { };
int main()
{
    D d;
    d.f();
}

请注意,最终覆盖器的概念适用于特定对象,而不是类:

对象的虚拟成员函数C::vf S是一个 最终覆盖器,除非派生最多的类 (1.8((其中 S 是基类子对象(如果有(声明或继承另一个成员 覆盖vf的函数。在派生类中,如果是虚拟成员 基类子对象的函数具有多个 final。 覆盖程序格式不正确。

粗体字是我的。

标准中的示例不使用虚拟继承。D中有两个A子对象 - 我们称它们为 A1A2A::fA1B A::f的最终覆盖者。 C::fC 中的最终覆盖器(A2没有最终覆盖器(。D 的定义格式良好,因为没有单个基类子对象,A::f D中有多个最终覆盖器。

在您的示例中,对于虚拟继承,只有一个 A 对象,它是 BC 的基类子对象。 A::f不是B的最终覆盖器,因为派生最多的类B是基类子对象(即D(继承了另一个覆盖A::f的成员函数(即C::f(。

因此,再一次,没有一个基类子对象A::f D中有多个最终覆盖器。 C::fCD对象中A::f的最终覆盖器; AB 对象没有最终覆盖程序。

实际上,此代码调用C::f

// Setup the same as in the OP's example:
D d;
B* pB = &d;
pB->f();  // calls C::f, not A::f