C++:纯虚函数 f 的参数 x 是否可以在 f 的派生类实现中替换为 x 的子类型?

标签 c++ oop inheritance abstract-class pure-virtual

考虑下面的抽象类,它将是将某个对象携带的信息写入标准输出的类的接口(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/

相关文章:

c++ - std::optional has_value() 怎么可能是 constexpr?

c++ - 需要有关类(class)的帮助

asp.net-mvc - Entity Framework - 选择特定列并返回强类型而不丢失强制转换

c++ - 异常 : bad_weak_ptr while shared_from_this

c++ - 在 visual studio 2008 中检查编译器版本

java - 关联关系和依赖关系有什么区别?

c++ - 扩展类

C++继承问题

c++ - 这个声明是什么意思?

php - 如何访问带有美元符号的 PHP 对象属性?