【问题标题】:How do C++ containers work together with the Liskov Substitution Principle?C++ 容器如何与 Liskov 替换原则一起工作?
【发布时间】:2017-08-27 10:30:42
【问题描述】:

对于返回类型的协方差Liskov 替换原则要求返回值。

让我们假设返回类型的小类型层次结构:

class B {};
class D : public B {};

那时工人阶级可以拥有

class Base {
    virtual B& func();
};
class Derived : public Base {
    virtual D& func();
};

这将符合LSP,因为返回类型是协变BaseDerived 的层次结构是“co”到BD)。

如果 容器 真的起作用了怎么办?

class Base {
    virtual vector<B>& func();
};
class Derived : public Base {
    virtual vector<D>& func();
};

这仍然符合 LSP 吗? vector&lt;B&gt;vector&lt;D&gt; 是否与 BaseDerived“协变”?

附加问题:如果我使用指针作为容器类型(允许动态多态性),即vector&lt;B*&gt; 等,它对 LSP 有影响吗?

注意:我尽量不依赖真正的 C++ 覆盖规则,但主要是想了解 LSP。我没有故意使用override 关键字。首先我想了解 LSP,然后我可以尝试 C++ 是否支持这些规则。

【问题讨论】:

    标签: c++ liskov-substitution-principle covariant covariant-return-types


    【解决方案1】:

    vector&lt;B&gt;vector&lt;D&gt; 是两个完全不相关的类型,因此不符合 LSP。

    vector&lt;B*&gt;vector&lt;D*&gt; 就 C++ 类型系统而言也是两个完全不相关的类型。由于BD 的基类,因此您可以同时使用vector&lt;B*&gt;,这样协方差就不是问题了。

    【讨论】:

    • 是的,看来C++不允许。但是vector&lt;D*&gt; 表现正确,不是吗?那么从计算机科学的角度来看,这可以吗?
    • vector&lt;D&gt; 不允许添加 B 类型的元素,所以不,它不能正确地替代 vector&lt;B&gt;D 的不可变向量会很接近,但你最终会遇到 C++ 的一个根本缺陷——它不支持这种类型的协方差。
    • @towi 你可以 reinterpret_cast vector&lt;D*&gt;vector&lt;B*&gt; 并且它会工作(在这种情况下)。你问的是这个吗?
    • 我认为是。我尝试将计算机科学映射到 C++ 实践中。顺便说一句:我喜欢你写“你可以”,因为我不会:-)
    猜你喜欢
    • 2010-12-03
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    相关资源
    最近更新 更多