带指针的钻石继承虚拟成员铸造
diamond inheritance virtual member casting with pointers
与THIS QUESTION:
相似但不完全相同
A
/ \
B C
\ /
D
我想要的是:
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
}
根据 THIS QUESTION 这似乎不是问题,只要继承只是多重继承而不是菱形。为什么这不适用于菱形?
显然它是模棱两可的,但我想做的是转换指针并因此使用虚函数的不同父实现,即:
((C*) p)->func(); //does C::func
如果我运行上面的代码我运行进入错误:
error: cannot convert from pointer to base class 'A' to pointer to derived class 'C' because the base is virtual
((C*)p)->func();
我试过 google 但找不到任何地方
由于 func
在整个层次结构中都是虚拟的,因此通过指向所涉及的任何类型的指针直接调用 func
都会调用 D::func
。要在问题的代码中进行转换,请使用 dynamic_cast<C*>(p)
。但这并没有消除 func
的虚拟性,因此最终会调用 D::func
,就像 p->func()
所做的那样。
要摆脱虚拟性,您必须命名 class 以及函数。在更简单的上下文中:
D *d = new D;
d->C::func(); // calls C::func
当您有指向基类型的指针而不是指向派生类型的指针时,您必须将指针转换为具有 C::func
的类型。该转换是使用 dynamic_cast
完成的,如下所示:
A *p = new D;
dynamic_cast<C*>(p)->C::func();
根据您的编译器,您可能需要 fiddle 使用您的 class 定义来消除链接器错误。一些编译器混淆了从 class 没有非内联函数的 es 的继承。
与THIS QUESTION:
相似但不完全相同 A
/ \
B C
\ /
D
我想要的是:
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
}
根据 THIS QUESTION 这似乎不是问题,只要继承只是多重继承而不是菱形。为什么这不适用于菱形?
显然它是模棱两可的,但我想做的是转换指针并因此使用虚函数的不同父实现,即:
((C*) p)->func(); //does C::func
如果我运行上面的代码我运行进入错误:
error: cannot convert from pointer to base class 'A' to pointer to derived class 'C' because the base is virtual
((C*)p)->func();
我试过 google 但找不到任何地方
由于 func
在整个层次结构中都是虚拟的,因此通过指向所涉及的任何类型的指针直接调用 func
都会调用 D::func
。要在问题的代码中进行转换,请使用 dynamic_cast<C*>(p)
。但这并没有消除 func
的虚拟性,因此最终会调用 D::func
,就像 p->func()
所做的那样。
要摆脱虚拟性,您必须命名 class 以及函数。在更简单的上下文中:
D *d = new D;
d->C::func(); // calls C::func
当您有指向基类型的指针而不是指向派生类型的指针时,您必须将指针转换为具有 C::func
的类型。该转换是使用 dynamic_cast
完成的,如下所示:
A *p = new D;
dynamic_cast<C*>(p)->C::func();
根据您的编译器,您可能需要 fiddle 使用您的 class 定义来消除链接器错误。一些编译器混淆了从 class 没有非内联函数的 es 的继承。