Arm*_*yan 6 c++ virtual-functions virtual-inheritance language-lawyer c++11
考虑以下菱形层次结构:
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
}
Run Code Online (Sandbox Code Playgroud)
就非虚拟功能g而言,一切都很清楚:名称B::g隐藏A::g,即使名称A::g可以在不被隐藏的情况下到达C.没有含糊之处.B::g叫做.该标准在10.2 p.10中明确证实了这一点:
[注意:当使用虚拟基类时,可以沿着不通过隐藏声明的子对象点阵的路径到达隐藏声明.这不是含糊不清的.与非虚拟基类相同的用法是模棱两可的; 在这种情况下,没有唯一的名称实例隐藏所有其他名称. - 尾注] [示例:
此外,对相关问题的这个答案提供了对该问题的详尽解释.
我不明白的是上面提到的引用如何与虚函数有关f.没有名字隐藏f,是吗?只涉及覆盖,10.3 p.2读取:
类对象S的虚拟成员函数C :: vf是最终覆盖,除非其中S是基类子对象(如果有)的最派生类(1.8)声明或继承覆盖vf的另一个成员函数.在派生类中,如果基类子对象的虚拟成员函数具有多个最终覆盖,则程序是格式错误的.
现在,在我看来,虚函数f完全符合没有最终覆盖的定义,程序应该是格式错误的.但事实并非如此.或者是吗?MSVC编译得很好,有以下警告:
警告C4250:'D':通过优势继承'B :: B :: f'
说实话,我之前从未遇到过"支配地位"这个词.当我在标准中搜索它时,它在索引中只出现一次,并引用我的第一个引用来自的章节.并且,正如我已经提到的,引用似乎只与名称隐藏而不是虚函数覆盖有关.
f有d不止一个最终置换器?我[10.3]/2再说一遍:
除非最大派生类(1.8)是基类子对象(如果有)声明或继承覆盖的另一个成员函数,否则
C::vf类对象的虚拟成员函数S是最终S覆盖vf.在派生类中,如果基类子对象的虚拟成员函数具有多个最终覆盖,则程序是格式错误的.
因此,在您的示例A::f中,不是最终的覆盖,因为D(最派生的类)继承B::f覆盖它.B::f是最终的覆盖者,所以它被称为.
如果有一个以上的最终覆盖(例如,如果C也是覆盖f),该程序将是不正确的,但只有一个,所以一切都很好.
Clang和GCC在没有一个警告的情况下编译它.
回答你的问题,关于C4250警告的文档准确地描述了你的情况,并且通过支配它显然意味着所描述的行为[10.3]/2.
| 归档时间: |
|
| 查看次数: |
359 次 |
| 最近记录: |