【问题标题】:Multiple inheritance in c++ with virtual functionsc++中的多重继承与虚函数
【发布时间】:2016-06-13 22:40:14
【问题描述】:

我有这个代码:

class A
{
public:
   virtual void FA()=0;
};

class B: public A
{
public:
    virtual void FB()=0;
};

class Imp_A: public A
{
public:
   void FA()
   {
      // implement FA
   }
};

class Imp_B :public Imp_A, public B
{
   public:
       void FB()
       {
           // implement FB by calling FA()
           FA();
           // do some more work here.
        }
};

在 Imp_B 类中,我不想实现 FA,因为它已经在该类所基于的 Imp_A 中实现了。

但是当我尝试编译我的代码时,我得到了 Imp_B 是虚拟的并且不能被实例化的错误。

当我尝试在 FB 中调用 FA 时,我收到错误提示 FA 不明确。

我该如何解决这个问题?

请注意 Imp_A 是基于 A 并实现它,Imp_B 是基于 Imp_A 和 B 的想法是它使用 imp_A 的 A 实现并且只实现 B。

【问题讨论】:

  • 你得到一个模棱两可的参考,因为它不知道是使用类A还是imp_A。为了解决这个问题,你需要在它前面加上你想要实现它的基类,所以如果你想使用 A 类,那么你可以输入A::FA。您不能实例化虚拟方法,但可以覆盖它们,因此您需要指定您正在覆盖该方法。我有一段时间没有使用 C#,所以我不记得确切的语法(因此我要评论而不是回答)。
  • @Vistari 这是 c++ 而不是 c#。由于在 Imp_A 中实现了 FA,为什么我不能实例化 Imp_B?
  • @mtk99 这不是那个问题的重复,因为这里 imp_A 基于 A 并且在那个问题上实现与虚拟类无关。
  • 你是对的,对不起
  • 实际错误是调用 FA(); 不明确(无法在来自 BA::FA 和来自 Imp_AA::FA 之间做出决定)。 “Imp_B 是虚拟的,不能被实例化”是一个应该被忽略的级联(它发生是因为FA(); 编译失败意味着FB() { .... } 没有编译,所以该类不被认为已经覆盖了纯虚拟定义)

标签: c++ multiple-inheritance virtual-functions


【解决方案1】:
class B: public A
{
public:
    virtual FB()=0;
}

您忘记将其显式声明为void,因此声明如下:

virtual int FB()=0;

您在Imp_B 中声明:

void FB();

这当然行不通。你没有覆盖那里的任何东西。

【讨论】:

  • 对不起,这是代码类型错误,我的原始代码在实现和接口上都是无效的。
【解决方案2】:

这看起来像经典的“钻石继承问题”,您在基类中定义了一个虚拟方法,该方法由两个或多个其他类继承,用作多重继承的源。

无论如何 - 虚拟继承是您问题的答案

class A
{
public:
   virtual void FA()=0;
}

class B: virtual public A
{
public:
    virtual void FB()=0; //probably a pure virtual function as well!?
}

class Imp_A: virtual public A
{
public:
   void FA()
   {
      // implement FA
   }
}

class Imp_B :public Imp_A, public B //since you call FA() you need it's implementation from Imp_A
{
   public:
       void FB()
       {
           // implement FB by calling FA()
           FA();
           // do some more work here.
        }
}

这里的问题是 Imp_b 最终得到来自两个 A 类定义的 FA 定义;使用虚拟继承有助于解决这个问题。

【讨论】:

  • 谢谢,这并没有解决问题:您的意思是虚拟公共 imp_A 吗?即使这样也没有解决问题。我仍然遇到同样的错误。
  • 好吧,我在这里编译了它:cpp.sh,它编译得很好;请注意,您的原始代码中有错字 FB() 需要返回类型。
  • 我想你还需要class Imp_A: virtual public Aclass Imp_B: public Imp_A。基本上,所有继承 A 的东西都需要虚拟继承。
  • @Pandrei 您能否在 cpp.sh 上分享您的代码,以便我可以通过我的实现来检查它?
  • @MartinBonner;不是你不使用 Imp_A 不用于多重继承,并且 Imp_B 不需要从 imp_A 继承它已经有来自 A 和 B 的两个 A 类定义
【解决方案3】:

你的继承shema或多或少:

   Imp_B
   /   \
Imp_A   B
  |     |
  A     A

这意味着您从 A 的两个不同实现继承。所以 Imp_A::FA 确实定义了但 B::A 没有定义,所以类 Imp_B 仍然是抽象的。它还解释了FA 不明确的错误,因为它可能是Imp_A::FAB::A

解决方法:

  • 您可以删除继承class B: public A。这样AFA 将只存在于一个分支中,所有分支都将被定义
  • 您可以将基类A 设为虚拟,这意味着Imp_B 中只存在一个实例:

    class B: virtual public A
    ...
    class Imp_A: virtual public A
    ...
    

【讨论】:

  • 另一种解决方案是明确指出Imp_A::FA()(或B::FA(),如果那个人有正文)
  • @M.M:您在 FB 中调用 FA 是正确的,但这并不能解决 Imp_B 在明确覆盖 B::FB 之前仍然是抽象的问题
  • 不确定你在说什么,Imp_B 中的void FB() 覆盖B 中的virtual void FB() = 0;
猜你喜欢
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2017-03-31
  • 2014-07-28
  • 2014-10-20
  • 2012-09-20
相关资源
最近更新 更多