C++虚方法的虚继承

C++ Virtual Inheritance of virtual method

struct A {
    virtual void foo() { std::cout << "a";};
};

struct B:public virtual A {
    void foo() { std::cout << "b";}
};

struct C:public virtual A {
    void foo() { std::cout << "c";}
};

struct D:public B, public C {

};
int main() {
    return 0;
}

所以这个在编译时给了我们以下错误:

 \main.cpp:16:8: error: no unique final overrider for 'virtual void A::foo()' in 'D'
 struct D:public B, public C {

如果我们要使 B 和 C 结构的继承成为非虚拟的,代码 正在编译 恰到好处,没有任何错误(当然,如果我们调用 dd.foo())。那么有什么区别呢?为什么我们虚拟继承我们的class会出错,而直接继承却不会出错?

使 A 成为 BC 虚拟 基础 class 确保 D 完全包含一个 A 个子对象[1]。为此,BC 都为 foo[2] 提供了最终覆盖,并且都被 D[=39 继承=][2],因此 Dfoo 有两个最终覆盖,使程序格式错误[2].

A不是BC的虚拟基础class,D将包含两个不同的 A 个子对象[1]。这些子对象中的每一个都将有自己继承的 foo[2].

的最终覆盖程序

[1]: N4140 §10.1 [class.mi]/4:

A base class specifier that does not contain the keyword virtual, specifies a non-virtual base class. A base class specifier that contains the keyword virtual, specifies a virtual base class. For each distinct occurrence of a non-virtual base class in the class lattice of the most derived class, the most derived object shall contain a corresponding distinct base class subobject of that type. For each distinct base class that is specified virtual, the most derived object shall contain a single base class subobject of that type.

[2]:§10.3 [class.virtual]/2(强调我的):

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, 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. For convenience we say that any virtual function overrides itself. A virtual member function C::vf of a class object S is a final overrider unless the most derived class of which S is a base class subobject (if any) declares or inherits another member function that overrides vf. In a derived class, if a virtual member function of a base class subobject has more than one final overrider the program is ill-formed.