4

首先,如果有另一篇帖子回答这个问题,我深表歉意,我发现的所有类似帖子都涉及钻石继承方案或定义的函数,而这不是。

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

例子:

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 类定义时,错误仍然存​​在。

有什么办法可以使这项工作?

4

3 回答 3

2

如果你SetAand中有 2 个普通函数B,那么using B::Set会告诉编译器如果你有类的对象AB和该对象的调用方法,如果没有明确定义SetB::Set将被调用。AB::Set

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

你可以在这里做什么

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

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

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

于 2012-02-12T18:14:13.653 回答
0

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

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

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

using不适用于您的情况,因为您有,A*因此编译器没有歧义。

如果您有:

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

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

于 2012-02-12T18:11:10.990 回答
0

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

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

于 2014-11-24T12:41:06.243 回答