我正在研究与多重继承相关的主题。我提出了以下代码,但无法完全弄清其背后的机制:
struct root
{
virtual void vfunction(){ /* root version */ }
};
struct mid1:public root
{
virtual void vfunction(){ /* mid1 version */ }
};
struct mid2:public root
{
virtual void vfunction(){ /* mid2 version */ }
};
struct inheritMulti:public mid1, public mid2
{
void ambiguityMethod(){
vfunction(); // error: ambiguous
}
void method1(){
mid1& t = *this;
t.vfunction();
}
void method2(){
mid2& t = *this;
t.vfunction();
}
};
ambiguityMethod
显然是一个错误。但是,在method1
和method2
中的函数调用使我感到困惑。它们也是虚拟函数调用,而t
实际上是inheritMulti
类型。因此他们应该调用inheritMulti
的vfunction
版本,但是由于inheritMulti
没有自己的版本,所以我不知道会发生什么。事实证明,在method1
中的呼叫称为mid1
版本,而在method2
中的呼叫称为mid2
版本。它是未定义的东西,只发生在我的编译器上吗?如果没有,为什么它会这样工作? vtable如何处理这种情况?谢谢!首先感谢您的帮助。我自己搜索过有关主题的文章,所以,我知道“钻石问题”。但我认为我的问题与此不同。我主要关心的是
method1
和method2
中“虚拟函数调用”的行为是标准定义还是未定义。在编译器中,它的行为类似于我上面提到的,但是标准所承诺的行为是吗?如果定义明确,为什么要分别调用mid1
和'mid2'版本? (直观的想法是调用inheritMulti
版本,因为t
的类型实际上是inheritMulti
。)而且,大多数编译器如何处理这种情况?奇怪的是,method1
和method2
中的虚拟函数调用调用了不同的函数。再次感谢! 最佳答案
void method1(){
mid1& t = *this;
t.vfunction();
}
在这里,您要调用在
vfunction
中未定义的inheritMulti
,因此它将搜索vfunction
中最接近的定义,而该定义在mid1
中存在。请参阅层次结构。根-> Mid1-> inheritMulti
根目录->中2->继承多
同样的情况
`void method2(){
mid2& t = *this;
t.vfunction();
}
在这里,在mid2中也找到了最接近的定义,因此得到了输出。这些调用不是模棱两可的,因为两个结构都在其中创建了自己的
vfunction
副本。inheritMulti
将有两个名为mid1
和mid2
的子对象,并且这些子对象中的每一个都维护自己的vtable指针。虽然您可能会认为mid1& t1 = *this;
和
mid2& t2 = *this;
t1和t2都相同,但是请尝试这样做...
bool same = ((void*)t1) == ((void*)t2); // Result false!
因为编译器在后面生成一些代码来调整指针以指向正确的对象。
关于c++ - 多态如何涉及多重继承?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31523742/