我有两个C ++类:Sequence
,就像std::vector
和File
,它是表示机器上文件的Sequence
个字符串。
从File
中获取Sequence
是明智之举。它的行为完全相同,但增加了读写文件的功能。 File
特定功能很容易实现,无需将Sequence
的数据成员标记为受保护。相反,它们可以是私有的,File
可以使用Sequence
的公共接口。欢乐时光到处都是。
我想创建一个Array
类,在内部管理动态分配的内存。 Array
对象无法调整大小;大小在构造函数中指定。*
这是事情变得有争议的地方。
从概念上讲,从Sequence
派生Array
是有意义的。正如File
是Sequence
并具有读取和写入文件的附加功能一样,Sequence
是Array
,具有按需调整大小的附加功能。
但是有一个关键区别:调整大小功能需要直接访问到内存Array
正在管理。换句话说,现在必须保护以前的私人成员。
使用受保护的成员而不是私有成员会破坏封装。 Array
和Sequence
之间的链接是唯一需要它的链接;作品中的其他课程可以使用父母的公共界面。从这个意义上说,推导出来是一个坏主意。
您可能会争辩说,想要数组的人只能使用Sequence
并忽略调整大小功能。但话说回来,您可以使用File
并忽略读/写功能。这就像买一台笔记本电脑但从未从你的办公桌上移动它。这根本没有意义。
什么是最好的举措:推导并潜在破坏封装;使Array
成为一个完全独立的课程,并且必须毫无意义地重新实现许多功能;或完全忘记Array
并让人们使用Sequence
?
* 请注意,这是一个充满乐趣和教育的项目,因此具有不可调整大小的动态分配数组的实用性是不可或缺的。
答案 0 :(得分:4)
您可能会考虑以稍微不同的方向切割问题。也许这个问题可以通过模板解决 - 而不是继承,特别是管理集合缓冲区的策略模板。你有(至少)两个实现:一个用于固定分配,另一个用于自动调整大小。
这根本不会破坏封装,几乎我可以在两者之间看到的唯一重叠是初始分配可能大致相同,无论是固定的还是变量的。鉴于这是多么微不足道,我怀疑是否值得花费大量时间或精力试图将其分解出来。理论上它可能是,但至少在一个典型的情况下,我们谈论的是一行代码,而且是一个非常简单的代码。
回到继承问题片刻,它归结为:这非常类似于标准圆与椭圆形的情况,其中一个看起来像另一个足够相似,但最终都不满足LSP - 你不能安全地将任何一个视为另一个,所以(至少是公共的)继承是不合适的。私有继承不需要跟随LSP,但通常只在/如果您需要/想要覆盖基类的虚函数时才有用,这似乎也不太可能。
答案 1 :(得分:4)
我不会在这里使用派生。
Sequence
实际上不是Array
。虽然实际上它们似乎有许多常用方法,但从设计的角度来看,它们具有非常不同的用途和保证。
但是,使用Array
中的Sequence
和Sequence
将Array
转发给template <typename T>
class Sequence
{
public:
Sequence(): _array(10) {}
explicit Sequence(size_t n): _array(n) {}
bool empty() const { return _size == 0; }
size_t size() const { return _size; }
size_t capacity() const { return _array.size(); }
private:
size_t _size; // current size
Array<T> _array;
}; // class Sequence
直接转发File
是有道理的。 :
Sequence
注意:我在这里假设Array是使用所有元素一次构建的,而序列将一次添加一个
同样,Sequence
来自{{1}}是否有意义?您是否有实施问题,例如将{{1}}的内容与磁盘表示同步?
答案 2 :(得分:3)
好吧,在你的情况下从Sequence
派生Array
公开继承是绝对坏主意(因为从矩形派生正方形)。在面向对象编程方面,序列不是一个数组,因为Array
具有Sequence
没有的属性,而且它是:An Array object cannot be resized
。如果你进行推导,它将会破坏Liskov substitution principle。
在你的情况下,由于你想要实现一些已经存在于另一个类中的功能,我建议你使用私有继承(这意味着继承实现)或组合,例如将Array
的实例存储在Sequence
的私有区域中,并将其用于内部实现。
UPD: 但是,使用Sequence
实施Array
在我看来也很成问题。也许创建一些抽象基类Container
可以更好地实现Sequence
和Array
的通用功能,然后从中派生这两个类。