首先我很抱歉,如果有另外一个帖子可以解答这个问题,我发现所有类似的帖子都涉及钻石继承方案或定义的函数,但事实并非如此。
简而言之,我想知道是否有可能让一个类继承自另外两个类,其中两个子类都有一个具有相同名称和参数的函数但是它在一个子类中定义,而纯虚拟在另一个。此外,如果我可以这样做,调用pure-virtual / abstract类上的函数最终会调用另一个子类上的已定义函数,而对派生类的更改最小?
示例:
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类定义时,错误仍然存在。
有什么方法可以让我的工作吗?
答案 0 :(得分:2)
如果Set
和A
中有2个正常函数B
,则using B::Set
会告诉编译器您是否有类AB
的对象如果未明确定义Set
,则会调用该对象的调用方法B::Set
,<{1}}。
你的情况有所不同。您有纯虚函数AB::Set
,它使A::Set
成为抽象类。由于A
未覆盖AB
,A::Set
也会变为抽象,这就是您无法实例化它的原因。
您可以实施AB
来致电AB::set
:
B::Set
此外,我不建议为基类使用相同的方法名称,因为我不建议使用多重继承,请尝试使用聚合。
答案 1 :(得分:0)
您是否尝试过实施该方法:
class AB : public A, public B
{
void Set(int X) {}
};
它不起作用的原因是A::Set()
是纯虚拟的。即它没有实施。但你试着打电话给它。您必须在派生类中重写它,以便能够实例化派生类。
using
在您的情况下不起作用,因为您有A*
,因此编译器没有歧义。
如果你有:
AB* ObjectA = new AB();
ObjectA->Set(Y);
您必须在using
声明中使用AB
来解决歧义。
答案 2 :(得分:0)
AB类派生自A,A有一个纯虚方法使类抽象,AB 必须实现在基类中声明的任何纯虚方法才能实例化。
我会尽量避免多重继承,这会引起很多麻烦,而且通常有更好的方法来解决问题,例如在这个例子中,我不理解从A和B得到的点,如果B实际上,共享实际上B应该来自A。