【问题标题】:Multiple Inheritance with abstract and defined inherited functions of the same name具有同名抽象和已定义继承函数的多重继承
【发布时间】:2012-03-04 07:17:52
【问题描述】:

首先我很抱歉,如果有另一个帖子可以回答这个问题,我发现的所有类似帖子都涉及菱形继承方案或定义的函数,而这不是。

简而言之,我想知道是否可以让一个类从其他两个类继承,其中两个子类都有一个具有相同名称和参数的函数,但它是在一个子类中定义的,并且是纯虚拟的其他。此外,如果我能做到这一点,调用纯虚拟/抽象类上的函数最终会调用另一个子类上定义的函数,而对派生类的更改最少?

例子:

class A
{
    public:
    virtual void Set(int X) = 0;
};

class B
{
    public:
    virtual void Set(int X);
};

class AB : public A, public B
{
    //other methods not relevant to example go here
};

int main(int argc, char **argv)
{
    int Y = 5;
    A* ObjectA = new AB();
    ObjectA->Set(Y);
    return 0;
}

到目前为止,我尝试编译这个基本示例时遇到了如下错误:

'AB' : 无法实例化抽象类 由于以下成员: 'void A::Set(int)' : 是抽象的

在进行自己的研究时,我找不到明确的答案,但根据其他涉及相关主题的问题,我发现在 AB 类中使用“使用 B::Set”可能会对此有所帮助。但是当我尝试将它添加到 AB 类定义中时,错误仍然存​​在。

我有什么办法可以完成这项工作吗?

【问题讨论】:

  • 第四行缺少virtual
  • 您的代码至少缺少一个virtual 说明符。请修复。
  • 现在我们知道为什么许多语言没有实现 MI,因为像你这样的人只需要做这样的事情。 :) :)
  • @TonyHopkinson:这个问题与 MI 无关。提问者只是对纯虚函数感到困惑。
  • 修复了虚拟的东西。 >.>

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


【解决方案1】:

如果你在AB 中有两个普通函数Set,那么using B::Set 会告诉编译器如果你有类AB 的对象并调用该对象的方法Set,@如果 AB::Set 未明确定义,则将调用 987654327@。

你的情况不同。你有纯虚函数A::Set 导致A 成为抽象类。由于AB 没有覆盖A::SetAB 也变得抽象,这就是你不能实例化它的原因。

你可以在这里做什么

可以实现AB::set调用B::Set

class AB : public A, public B
{
public:
    void Set(int x) { return B::Set(x); }
};

另外我不推荐基类使用相同的方法名,因为我不推荐多重继承,尝试使用聚合代替。

【讨论】:

    【解决方案2】:

    您是否尝试过实现该方法:

    class AB : public A, public B
    {
        void Set(int X) {}
    };
    

    它不起作用的原因是A::Set() 是纯虚拟的。 IE。它没有实现。但是您尝试调用它。您必须在派生类中重写它才能实例化派生类。

    using 在你的情况下不起作用,因为你有一个A*,所以编译器没有歧义。

    如果你有:

    AB* ObjectA = new AB();
    ObjectA->Set(Y);
    

    您必须在 AB 的声明中使用 using 来解决歧义。

    【讨论】:

    • 我想到了这样做,是的。但是,我希望有一个更精简的解决方案,因为我想最小化将抽象类与其他类集成所涉及的代码。在这种情况下,“AB”和“B”类可以是我的应用程序中的许多不同的类。无论如何,如果这是我必须做的,那就是我必须做的。如果没有很快出现更精简的答案,我会接受这个作为答案。谢谢。
    • @Mako_Energy 不会有正确的答案告诉您如何实例化抽象类。由于您不覆盖基本抽象方法,因此您的类是抽象的。没有办法解决这个问题。
    【解决方案3】:

    AB 类派生自 A,A 具有使类抽象的纯虚方法,AB必须实现基类中声明的任何纯虚方法才能被实例化。

    我会尽量避免多重继承,它会引起很多麻烦,并且通常有更好的方法来解决问题,例如在这个例子中,我不明白从 A 和 B 派生的意义,如果 B 共享并且实际上实现了与 A 相同的接口,那么 B 肯定应该从 A 派生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-05
      • 2013-01-03
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      • 2023-03-05
      • 2011-03-10
      • 1970-01-01
      相关资源
      最近更新 更多