具有相同名称的抽象和已定义继承函数的多重继承

Multiple Inheritance with abstract and defined inherited functions of the same name

本文关键字:定义 继承 函数 多重继承 抽象      更新时间:2023-10-16

首先,如果有另一篇帖子回答了这个问题,我很抱歉,我发现的所有类似的帖子都涉及钻石继承方案或定义的函数,但事实并非如此。

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

示例:

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::集"可能会有所帮助。但是当我尝试将它添加到AB类定义中时,错误仍然存在。

有什么办法让我做这件事吗?

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

你的情况不同。您有一个纯虚拟函数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); }
};

此外,我不建议基类使用相同的方法名,因为我不建议多重继承,请尝试使用聚合。

您尝试过实现方法吗:

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

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

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

如果你有:

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

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

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

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