我正试图在 C++ 中找到一个很好的继承解决方案。
我有一个 Rectangle 类和一个 Square 类。 Square 类不能公开继承自Rectangle,因为它不能完全满足矩形的要求。例如,一个矩形可以分别设置其宽度和高度,而这对于方形当然是不可能的。
所以,我的困境。 Square 显然会与 Rectangle 共享很多代码;它们非常相似。
例如,如果我有这样的函数:
bool IsPointInRectangle(const Rectangle& rect);
它也应该适用于正方形。事实上,我有很多这样的功能。
所以在制作我的 Square 类时,我想我会使用私有(private)继承和一个可公开访问的 Rectangle 转换运算符。所以我的方形类看起来像:
class Square : private Rectangle
{
public:
operator const Rectangle&() const;
};
但是,当我尝试将 Square 传递给 IsPointInRectangle 函数时,我的编译器只是在该上下文中提示“Rectangle is an accessible base”。我希望它注意到 Rectangle 运算符并改用它。
我正在尝试做的事情是否可行?
如果这行不通,我可能会将 Rectangle 的一部分重构为 MutableRectangle类。
谢谢。
最佳答案
你可以创建一个 ImmutableRectangle
类,没有任何修改器,只有 const
方法,你可以从中正确地派生 Rectangle
,和,分别是 ImmutableSquare
和 Square
。请注意,除去可变性,IS-A
关系确实 成立——一个不可变的正方形 IS-A 一个不可变的矩形:可变性是唯一严重的问题,因此通过分解它out 你可以获得一些实质性的代码重用(对于所有 const
用途——那些实际上不使用或不需要可变性的用途)。
只要(不可变)基类的类不变量实际上依赖不变性特性,就可以沿继承引入可变性;当然,可以从 const
指针或对可变版本的引用正确构造一个不可变对象(immutable对象)(大概在一个单独的内联友元函数中,以避免使基类依赖于派生类;-)以方便使用。
编辑:可以理解的是,一条评论表达了疑虑,因为“a mutabe is not an immutable”:要对此进行推理,您需要了解“IS-A”的含义 ...它不意味着Korzybski -拒绝“是
身份”:这意味着LSP .通过约束的繁琐,这意味着:协变、逆变、弱等前置条件、强等后置条件等,因为它们适用于基类的 const 方法 (不可变的)和派生的(可变的)类。正如我在上一段中提到的,您会看到类不变量是唯一的问题,因此只要避免将不变性断言为类不变量,您就处于三叶草状态;-)。
也许将基类命名为 NotNecessarilyMutableRectangle
会有所帮助,因为它不会断言不变性作为类不变性;非常精确的命名可能在哲学上令人放心,但在日常编码中可能有点不方便。
关于C++ 隐式转换运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2483491/