我正在经历这个: - https://isocpp.org/wiki/faq/multiple-inheritance#mi-delegate-to-sister
有人可以解释一下这是怎么发生的,为什么会发生这种情况?
答案 0 :(得分:9)
其他两个答案中缺少的关键是存在虚拟继承。这意味着在完整对象中只有一个 Base
子对象,由Der1
和Der2
共享。
Der1
和Der2
类型中的每一个都提供了该基础的一个虚函数的实现,并且由于只有一个这样的对象,Der1
和Der2
的组合Base
在完整对象中提供两个成员的实现。
您可以调度到兄弟类,因为您实际上正在调用Base
类型的成员函数,并且该函数已在您的Der1
子对象中实现(通过您的兄弟类)。请注意,Der2::bar
不会调用Base::bar
,而是调用Der2
,然后将其调度到恰好位于struct base { virtual void f() = 0; };
struct d : base { void g() { f(); } };
struct d1 : d { void f() { std::cout << "here"; };
int main() {
d1 x;
x.g(); // dispatches from 'd::g' to 'd1::f' which is below in the hierarchy!
// yeah, right, everyone knows that... no magic here
}
的最终覆盖者。在其他情况下,这与发送到最终覆盖者的情况没有什么不同:
Base
现在,如果继承不是虚拟的,那么完整类型中将有两个{{1}}个子对象,每个子对象都有一个(不同的)纯虚函数,你甚至无法实例化最派生类型的对象(除非提供了虚函数的定义)
答案 1 :(得分:1)
因为这是虚函数,而调用是从VirtualFunction表调用函数。它只是通过定义的索引在表中查找。这个表在构造对象时获取数据,并且由于对象的动态类型是Join,并且此类型具有从基类继承的所有虚函数的条目。
答案 2 :(得分:1)
简短回答是:
虽然Join类派生自Der1和Der2,但只有一个Base类实例。那是因为虚拟继承。如果Base类不是抽象类,并且你必须将一些参数传递给构造函数,那么Der1和Der2中都会省略这些调用,你必须通过Join传递这些参数。