[英]diamond inheritance virtual member casting with pointers
Similar, but not identical to, THIS QUESTION : 与这个问题类似,但不相同:
A
/ \
B C
\ /
D
What I want is: 我想要的是:
struct A { virtual void func (void) = 0; };
struct B : virtual A { void func (void) {} };
struct C : virtual A { void func (void) {} };
struct D : B,C { void func (void) {} };
int main ()
{
A *p = new D();
((C*) p)->func(); // do C::func
((B*) p)->func(); // do B::func
}
According to THIS QUESTION this does not seem to be a problem so long the inheritance is just multiple inheritance and not a diamond. 根据这个问题,这似乎不是问题,只要继承只是多重继承而不是钻石即可。 why does this not work with a diamond shape? 为什么这不适用于菱形形状?
Apparently its ambiguous, but what I want to be able to do is cast the pointer and hence use a different parent implementation of the virtual function, ie: 显然它是模棱两可的,但是我想做的是强制转换指针,因此使用了虚函数的另一个父实现,即:
((C*) p)->func(); //does C::func
If I run the code above I run into the error: 如果运行上面的代码,则会遇到错误:
error: cannot convert from pointer to base class 'A' to pointer to derived class 'C' because the base is virtual
((C*)p)->func();
which I tried to google but cannot find anywhere 我试图谷歌,但找不到任何地方
Since func
is virtual throughout the hierarchy, any direct call to func
through a pointer to any of the types involved will call D::func
. 由于func
在整个层次结构中都是虚拟的,因此通过指向所涉及的任何类型的指针对func
任何直接调用都将调用D::func
。 To do the cast in the code in the question, use dynamic_cast<C*>(p)
. 要进行问题代码的转换,请使用dynamic_cast<C*>(p)
。 But that doesn't remove the virtual-ness of func
, so that will end up calling D::func
, just as p->func()
does. 但这并不能消除func
的虚拟性,因此最终会像p->func()
一样调用D::func
。
To get rid of the virtual-ness, you have to name the class as well as the function. 要摆脱虚拟性,您必须命名类以及函数。 In a simpler context: 在更简单的上下文中:
D *d = new D;
d->C::func(); // calls C::func
When you have a pointer to the base type instead of a pointer to the derived type you have to convert the pointer to a type that has C::func
. 当您拥有指向基本类型的指针而不是指向派生类型的指针时,必须将指针转换为具有C::func
的类型。 That conversion is done with dynamic_cast
, like this: 该转换是通过dynamic_cast
完成的,如下所示:
A *p = new D;
dynamic_cast<C*>(p)->C::func();
Depending on your compiler, you might have to fiddle with your class definitions a bit to get rid of linker errors. 根据您的编译器,您可能需要稍微修改类定义才能摆脱链接器错误。 Some compilers get confused with inheritance from classes with no non--inline functions. 一些编译器会混淆没有非内联函数的类的继承。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.