令我惊讶的是,以下C ++代码无法编译。
class InterfaceA {
public:
virtual void Foo() = 0;
};
class InterfaceB : public InterfaceA {
public:
virtual void Bar() = 0;
};
class ImplementationA : public InterfaceA {
public:
void Foo() override {}
};
class ImplementationB : public ImplementationA, public InterfaceB {
public:
void Bar() override {}
};
int main() {
ImplementationB b;
b.Bar();
}
抽象类类型的对象" ImplementationB"不被允许: 纯虚函数" InterfaceA :: Foo"没有重写。 错误C2259' ImplementationB':无法实例化抽象类。
是否可以从Implementation A继承纯虚方法的实现,而无需在ImplementationB中重新定义Foo方法:
void Foo() override {
ImplementationA::Foo();
}
如果没有那么为什么?
答案 0 :(得分:3)
是的,为了达到你所需要的,你需要使用虚拟的不和。
一些细节: 就像现在一样,您的ImplementationB有两个父母,每个父母都是InterfaceA的独立后代。因此,您在ImplementationB中有2个InterfaceA副本 - 一个继承自ImplementationA并重写了Foo(),另一个继承自InterfaceA,并且没有Foo overriddent。虚拟继承(不要与虚函数混淆!)将确保您只有一个副本 - 覆盖所有内容的副本。
答案 1 :(得分:2)
你有钻石问题。因此,您应该使用虚拟继承。
正确的代码:
class InterfaceA {
public:
virtual void Foo() = 0;
};
class InterfaceB : public virtual InterfaceA {
public:
virtual void Bar() = 0;
};
class ImplementationA : public virtual InterfaceA {
public:
void Foo() override {}
};
class ImplementationB : public ImplementationA, public InterfaceB {
public:
void Bar() override {}
};
int main() {
ImplementationB b;
b.Bar();
}