如何继承纯虚函数C++的实现
How to inherit Implementation of pure virtual function C++
令我惊讶的是,以下 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();
}
object of abstract class type "ImplementationB" is not allowed:
pure virtual function "InterfaceA::Foo" has no overrider.
Error C2259 'ImplementationB': cannot instantiate abstract class.
是否可以从实现A中继承纯虚方法的实现,而无需在实现B中重新定义方法Foo为:
void Foo() override {
ImplementationA::Foo();
}
如果不是,那是为什么?
是的,要实现您需要的功能,您需要使用虚拟继承。
一些细节:
现在,您的 ImplementationB 有两个父级,每个都是 InterfaceA 的独立后代。结果,您的 ImplementationB 中有 InterfaceA 的 2 个副本 - 一个继承自 ImplementationA 并覆盖了 Foo(),另一个继承自 InterfaceA,并且没有覆盖 Foo。虚拟继承(不要与虚函数混淆!)将确保您只有一个副本 - 覆盖所有内容的副本。
您遇到钻石问题。因此,你应该使用虚拟继承。
正确代码:
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();
}
令我惊讶的是,以下 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();
}
object of abstract class type "ImplementationB" is not allowed: pure virtual function "InterfaceA::Foo" has no overrider. Error C2259 'ImplementationB': cannot instantiate abstract class.
是否可以从实现A中继承纯虚方法的实现,而无需在实现B中重新定义方法Foo为:
void Foo() override {
ImplementationA::Foo();
}
如果不是,那是为什么?
是的,要实现您需要的功能,您需要使用虚拟继承。
一些细节: 现在,您的 ImplementationB 有两个父级,每个都是 InterfaceA 的独立后代。结果,您的 ImplementationB 中有 InterfaceA 的 2 个副本 - 一个继承自 ImplementationA 并覆盖了 Foo(),另一个继承自 InterfaceA,并且没有覆盖 Foo。虚拟继承(不要与虚函数混淆!)将确保您只有一个副本 - 覆盖所有内容的副本。
您遇到钻石问题。因此,你应该使用虚拟继承。
正确代码:
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();
}