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
成为 B
和 C
的 虚拟 基础 class 确保 D
完全包含一个 A
个子对象[1]。为此,B
和 C
都为 foo
[2] 提供了最终覆盖,并且都被 D
[=39 继承=][2],因此 D
对 foo
有两个最终覆盖,使程序格式错误[2].
当A
不是时B
和C
的虚拟基础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.
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
成为 B
和 C
的 虚拟 基础 class 确保 D
完全包含一个 A
个子对象[1]。为此,B
和 C
都为 foo
[2] 提供了最终覆盖,并且都被 D
[=39 继承=][2],因此 D
对 foo
有两个最终覆盖,使程序格式错误[2].
当A
不是时B
和C
的虚拟基础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.