C++ 抽象基类的不明确继承:

C++ 抽象基类的不明确继承:,c++,C++,我有一个比这复杂得多的类结构,但将问题归结为其本质,这描述了我的场景:我有两个类,a和B,它们实现共享一个共同祖先的纯虚拟基类,然后是第三个类C,它们构成a和B。最后,填充纯虚拟基中常用方法的模板类: struct I { virtual void r()=0; }; struct A : I {}; struct B : I {}; struct C : A, B { void q(){ r(); // the problem is here.

我有一个比这复杂得多的类结构,但将问题归结为其本质,这描述了我的场景:我有两个类,a和B,它们实现共享一个共同祖先的纯虚拟基类,然后是第三个类C,它们构成a和B。最后,填充纯虚拟基中常用方法的模板类:

struct I {
  virtual void r()=0;
};

struct A : I {};
struct B : I {};

struct C : A, B {
  void q(){
    r();              // the problem is here.
  }
};

struct D : C {
  virtual void r(){
  }
};

C* c = new D;
c->q();
我的问题是,我找不到任何方法让C::q调用r()

如何从C中调用r()方法,以便调用正确的虚方法


对不起,我应该澄清虚拟继承不能在这里使用。我找到了两种解决办法:

struct C : A, B {
  virtual void r()=0;
  ...


这两种方法似乎都能充分消除对r()的调用的歧义,以便解决所有问题。

在C中将方法r重新声明为纯虚拟:

struct C : A, B {
  void q(){
    r();              // the problem is here.
  }

  virtual void r()=0;
};

告诉编译器要遵循层次结构的哪一部分:

struct C : A, B {
  void q(){
    A * p = this;
    p->r();              // recent GCC compiles this
  }
};

尝试虚拟继承

struct A : virtual  I {};
struct B : virtual I {};

这是不明确的,因为编译器不知道调用哪个
r()
,一个来自A,一个来自B

简单的方法是写:

static_cast<A*>(this)->r();
现在,你可以打电话了

void C::q() { r(); }

如你所料。对此的简单解释是,通过使用virtual,类C只获得接口I的一个“副本”,而不是两个。这消除了代码的歧义。

您没有在子结构中重载r(),因此它仍然是纯虚拟的。i、 e没有实现。

+1用于解决您的问题并将其分解为最简单的形式。在没有虚拟继承的C中,r()不是不明确吗?您指的是虚拟基类还是抽象基类?因为要使
I
成为一个虚拟基,您需要
struct a:virtuali{}
结构B:虚拟I{}
@DumbCoder:r在编译器看来是不明确的,但事实并非如此。它实现的唯一地方是D。这就是问题所在@查尔斯:不幸的是,这代表了COM继承问题,虚拟基类不能与COM混合没有真正的帮助,至少标准说这仍然是不明确的。你不应该使用动态的而不是静态的?这涉及到虚拟功能。不,你是向上的层次结构,而不是向下的。不知道为什么这是公认的答案。这是一个黑客。正确的答案实际上是继承自我。通常我会同意。但在我的情况下,我不能使用虚拟继承。在所有非虚拟继承解决方案中,这是最优雅的。
static_cast<A*>(this)->r();
static_cast<B*>(this)->r();
struct A : virtual I {};
struct B : virtual I {};
void C::q() { r(); }