考虑下面的抽象类,它将是将某个对象携带的信息写入标准输出的类的接口(interface)。
class FileBuilder
{
public:
virtual void build(const Object& object) = 0;
virtual ~FileBuilder() = default;
};
在这一点上我会注意到Object
也是一个具有派生类SpecialObject
的抽象类。现在我要实现SpecialFileBuilder : FileBuilder
,如下所示。
class SpecialFileBuilder : public FileBuilder
{
public:
void build(const SpecialObject& specialObject);
};
...
void SpecialFileBuilder::build(const SpecialObject& specialObject)
{
// Do some stuff
}
我不完全理解为什么这不可能。 SpecialFileBuilder
遵循接口(interface) FileBuilder
,任何需要 FileBuilder
的地方都可以被赋予 SpecialFileBuilder
。提前感谢您的帮助。
当然,如果我将内容更改为以下内容,这将起作用。
void SpecialFileBuilder::build(const Object& object)
但是,在我的 SpecialFileBuilder::build()
实现中,我需要使用参数是一个 SpecialObject
而不仅仅是一个 Object
。
我应该如何处理这个设计?
最佳答案
TL;DR 不,这没有任何意义。
下面是完整版。
I don't fully understand why this should not be possible.
virtual void build(const Object& object) = 0;
此声明是一个 promise 。它 promise build
可以接受 any Object
作为参数。此类 promise 对派生类具有法律约束力,即它们必须实现基类声明的 promise 。请注意,该声明并不 promise build
可以接受某些对象而不能接受其他对象。
FileBuilder* builder = GetBuilder(); // we don't know what kind of builder it is
SpecialObject some;
builder->build(some); // must work
OtherSpecialObject some;
builder->build(other); // must work too
UnrelatedObject whatever;
builder->build(whatever); // must work as well
现在看另一个声明
void build(const SpecialObject& specialObject);
它违背了 promise 。最初的 promise 是强大的。给我任何对象,我都能处理。新的 promise 是微弱的。哦,我是一个特殊的小 builder ,我只能应付特殊的小 object !
对不起,伙计,你不能用一个较弱的 promise 来覆盖一个强有力的 promise 。如果您被允许,我们如何能够相信任何 promise ?
现在如果你的设计不符合这个大纲,即你总是知道你得到什么样的构建器,并且你不想 promise 应付各种对象,那么你选择了一个错误的工具工作。也许您想尝试一下泛型编程。
template <typename T>
class FileBuilder {
virtual void build (const T& t) = 0;
};
class SpecialBuilder: public FileBuilder<SpecialObject> {
void build (const SpecialObject& t) override;
};
现在上面的代码不起作用,我们需要修复它
FileBuilder<SpecialObject>* builder = GetBuilder<SpecialObject>(); // we know exactly what we want to build
SpecialObject some;
builder->build(some); // will work;
OtherSpecialObject other;
builder->build(other); // sorry that's not in the contract, won't compile
关于C++:纯虚函数 f 的参数 x 是否可以在 f 的派生类实现中替换为 x 的子类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57337877/