什么是虚拟功能背景下的主导地位

What is dominance in the context of virtual functions?

本文关键字:主导地位 背景 功能 虚拟 什么      更新时间:2023-10-16

代码示例:

考虑以下菱形层次结构:

struct A
{
    virtual void f(){}
    void g(){}
};    
struct B : virtual A
{
    virtual void f() override{}
    void g(){}
};     
struct C : virtual A
{   
};    
struct D: B, C
{    
};
int main()
{
    D d;
    d.f(); //B::f is called
    d.g(); //B::g is called
}

我的理解:

就非虚拟函数g而言,一切都很清楚:名称B::g隐藏了A::g,即使名称A::g可以在不通过C隐藏的情况下到达。没有歧义。调用CCD_ 6。该标准在10.2 p.10:中明确确认了这一点

[注意:当使用虚拟基类时,可以通过不通过隐藏声明的子对象晶格。这并非模棱两可。相同的与非虚拟基类一起使用是不明确的;在这种情况下,没有唯一的名称实例把其他人都藏起来。——尾注][示例:

此外,对一个相关问题的回答对这个问题作了详尽的解释。

问题:

我不明白的是,上面提到的引用是如何与虚拟函数f相关的。f不存在隐藏名称的问题,是吗?只涉及覆盖,第10.3页第2页显示:

类对象S的虚拟成员函数C::vf是finaloverrider,除非S为基的最派生类(1.8)类子对象(如果有)声明或继承另一个成员函数它覆盖vf。在派生类中,如果的虚拟成员函数基类子对象有多个最终覆盖程序不正规。

现在,在我看来,虚拟函数f完全符合的定义,而不是有一个最终的重写器,程序应该是格式错误的。但事实并非如此。还是这样?MSVC编译得很好,并发出以下警告:

警告C4250:"D":通过优势继承"B::B::f"

老实说,我以前从未遇到过"统治力"这个词。当我在标准中搜索它时,它在索引中只出现一次,并将我引用到我的第一句话来源的章节。而且,正如我已经提到的,这句话似乎只适用于名称隐藏,而不是虚拟函数覆盖。

问题:

  • f在D中是否有一个以上的最终覆盖者
  • 优势规则是否适用于这种情况?它是如何遵循标准的

我将再次引用[10.3]/2:

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

因此,在您的示例中,A::f不是最终的覆盖器,因为D(派生最多的类)继承了覆盖它的B::fB::f是最终的覆盖者,因此它被调用。

如果有一个以上的最终覆盖器(例如,如果C也覆盖了f),程序将是不正确的,但只有一个,所以一切都很好。

Clang和GCC编译时没有任何警告。

在回答您的问题时,C4250警告的文档准确地描述了您的情况,而优势显然意味着[10.3]/2中描述的行为。