以下代码仅在您取消注释行
时才有效 virtual void FuncA() { ImplA::FuncA(); }
在类ImplB
中,否则我得到编译器错误:
无法实例化抽象类... FuncA(void)':是抽象的
问题是为什么它没有从继承的FuncA()
获得ImplA
的工具?
class InterfaceA {
public:
virtual void FuncA()=0;
};
class InterfaceB : public InterfaceA {
public:
virtual void FuncB()=0;
};
class ImplA : public InterfaceA {
public:
virtual void FuncA() { printf("FuncA()\n"); }
};
class ImplB : public ImplA, public InterfaceB {
public:
// virtual void FuncA() { ImplA::FuncA(); }
virtual void FuncB() { printf("FuncB()\n"); }
};
{
ImplB *b = new ImplB();
InterfaceA *A= b;
A->FuncA();
InterfaceB *B= b;
B->FuncB();
B->FuncA();
}
答案 0 :(得分:3)
您已经点击了"钻石"多重继承中的问题。 您需要使用"虚拟"继承(相当于在继承时添加关键字virtual)
问题是ImplB有两个到基类InterfaceA的路径。但是,您的意图是接口不提供任何实现。因此,您需要向编译器指出这一点,以便它可以统一纯虚函数。
更好的解释: http://www.cprogramming.com/tutorial/virtual_inheritance.html
我从接口继承后修改了代码以添加虚拟代码。现在它编译,即使行评论。另请注意,我认为您缺少虚拟析构函数,因此您还会遇到其他一些问题。此代码编译,而不会取消注释FuncA。
#include <cstdio>
class InterfaceA {
public:
virtual void FuncA()=0;
};
class InterfaceB : public virtual InterfaceA {
public:
virtual void FuncB()=0;
};
class ImplA : public virtual InterfaceA {
public:
virtual void FuncA() { printf("FuncA()\n"); }
};
class ImplB : public ImplA, public virtual InterfaceB {
public:
// virtual void FuncA() { ImplA::FuncA(); }
virtual void FuncB() { printf("FuncB()\n"); }
};
int main()
{
ImplB *b = new ImplB();
InterfaceA *A= b;
A->FuncA();
InterfaceB *B= b;
B->FuncB();
B->FuncA();
}
答案 1 :(得分:0)
多重继承不是“mixins”
您可以从具有相同名称但不会使它们相同的方法的多个类继承。
从虚拟类继承的东西必须实现其父类的纯虚函数。
如果方法名称没有作用域,则最终可能会出现互相排斥的父类组合,因为具有共享名称的方法的实现将不兼容。
我有点惊讶的是,将using ImplA::FuncA;
置于ImplB并没有解决它,但是:https://gcc.godbolt.org/