Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 带指针的菱形继承虚拟成员转换_C++_Multiple Inheritance - Fatal编程技术网

C++ 带指针的菱形继承虚拟成员转换

C++ 带指针的菱形继承虚拟成员转换,c++,multiple-inheritance,C++,Multiple Inheritance,类似于但不完全相同于: 我想要的是: 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)->f

类似于但不完全相同于:

我想要的是:

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
}
根据这一点,只要继承是多重继承而不是菱形继承,似乎就不是问题。为什么这不适用于菱形

显然,它是不明确的,但我希望能够做的是转换指针,从而使用虚拟函数的不同父实现,即:

((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\u cast(p)
。但这并没有消除
func
的虚拟性,因此最终将调用
D::func
,就像
p->func()
一样

为了消除虚拟性,您必须命名类和函数。在更简单的情况下:

D *d = new D;
d->C::func(); // calls C::func
如果有指向基类型的指针而不是指向派生类型的指针,则必须将指针转换为具有
C::func
的类型。该转换通过
dynamic\u cast
完成,如下所示:

A *p = new D;
dynamic_cast<C*>(p)->C::func();
A*p=新的D;
动态_cast(p)->C::func();

根据编译器的不同,您可能需要稍微修改类定义以消除链接器错误。一些编译器会对没有非内联函数的类的继承感到困惑。

“为什么这不适用于菱形”-您对“工作”的定义、您期望这段代码会做什么以及它实际做什么,对这个问题都很重要,而且应该是。在回答这个问题时,没有任何内容解释像
((C*)p)->func()
是可能的,或者它为什么被取消。两个声称的重复项都没有解决这里提出的问题。这个问题不是关于如何使用虚拟继承,而是关于从基指针转换为派生指针。如果您想要直接父实现,则需要指定要直接调用的实现。否则虚拟成员将获胜。尽管语法不同,。谢谢你,这正是我想要的
p->C::func()
奇怪的语法,非常有趣,非常感谢
A *p = new D;
dynamic_cast<C*>(p)->C::func();