抽象基类的模糊继承:

时间:2010-11-26 08:57:18

标签: c++

我有一个比这更复杂的类结构,但把问题归结为它的本质,这描述了我的场景:我有两个类,A& B,实现共享共同祖先的纯虚拟基类,然后是包含A& A的第三类C。 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()。

void C::q(){
  r();    // is ambiguous
  A::r(); // is pure virtual
  B::r(); // also is pure virtual
  D::r(); // C doesn't know about D
  ((D*)this)->r(); // is dubious and requires C to know about D.
}

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


抱歉,我应该澄清一下,这里不能使用虚拟继承。我找到了两个解决方案:

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

OR

struct C : A, B {
   using A::r;
   ...

两者似乎都足以消除对r()的调用的歧义。

5 个答案:

答案 0 :(得分:4)

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

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

  virtual void r()=0;
};

答案 1 :(得分:3)

尝试虚拟继承

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

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

简单的方法是写:

static_cast<A*>(this)->r();

static_cast<B*>(this)->r();

但我认为这一点都不是您正在寻找的答案。通过继承virtual接口I:

来清理情况
struct A : virtual I {};
struct B : virtual I {};

现在,您可以致电

void C::q() { r(); }
正如你所料的那样。 简单的解释是,通过使用虚拟,类C只获得接口I的一个“副本”,而不是两个。这消除了您的代码歧义。

答案 4 :(得分:-1)

你没有在子结构中重载r(),所以它仍然是纯虚拟的。即没有实施。