其他分享
首页 > 其他分享> > c – 子类/继承标准容器?

c – 子类/继承标准容器?

作者:互联网

我经常在Stack Overflow上阅读这些语句.就个人而言,我没有发现任何问题,除非我以多态方式使用它;即我必须使用虚拟析构函数.

如果我想扩展/添加标准容器的功能那么什么是比继承一个更好的方法?将这些容器包装在自定义类中需要更多的努力并且仍然是不洁净的.

解决方法:

这有一个坏主意有很多原因.

首先,这是一个坏主意,因为标准容器没有虚拟析构函数.你不应该使用没有虚拟析构函数的多态的东西,因为你无法保证派生类的清理.

Basic rules for virtual dtors

其次,这是非常糟糕的设计.实际上有几个原因是糟糕的设计.首先,您应该始终通过一般操作的算法扩展标准容器的功能.这是一个简单的复杂性原因 – 如果你必须为它应用的每个容器编写一个算法,你有M个容器和N个算法,那就是你必须编写的M x N方法.如果您通常编写算法,则只能使用N算法.所以你可以获得更多的重用.

它也是非常糟糕的设计,因为你通过继承容器来打破良好的封装.一个好的经验法则是:如果您可以使用类型的公共接口执行所需的操作,请在该类型的外部创建新的行为.这改善了封装.如果它是您想要实现的新行为,请将其设置为命名空间作用域函数(如算法).如果要强制使用新的不变量,请在类中使用包含.

A classic description of encapsulation

最后,一般来说,您永远不应该将继承视为扩展类行为的手段.这是由于对重用的思考不清晰而引起的早期OOP理论的重大坏处之一,即使有一个明确的理论为什么它是坏的,它仍然被教导和推广到今天.当您使用继承来扩展行为时,您将这种扩展行为绑定到您的接口契约,以便将用户的手与未来的更改联系起来.例如,假设您有一个类型为Socket的类,它使用TCP协议进行通信,并通过从Socket派生类SSLSocket并在Socket之上实现更高SSL堆栈协议的行为来扩展它的行为.现在,假设你有一个新的要求,即通过USB线或通过电话获得相同的通信协议.您需要将所有工作剪切并粘贴到从USB类或Telephony类派生的新类中.而现在,如果你发现了一个bug,你必须在所有三个地方修复它,这并不总是会发生,这意味着错误会花费更长的时间并且不会总是得到修复……

这对任何继承层次结构都是通用的A-> B-> C-> …当你想要使用你在派生类中扩展的行为,比如B,C,..在不是基础的对象上A类,你必须重新设计或者你正在重复实现.这导致非常单一的设计很难改变(想想微软的MFC,或他们的.NET,或者 – 好吧,他们犯了很多错误).相反,你应该尽可能地考虑通过构图进行扩展.在考虑“开放/封闭原则”时应该使用继承.您应该通过继承类具有抽象基类和动态多态运行时,每个都将完全实现.层次结构不应该很深 – 几乎总是两个层次.当您拥有不同的动态类别时,只能使用两个以上的动态类别,这些类别需要区分类型安全性的各种功能.在这些情况下,使用抽象基础直到叶类,它们具有实现.

标签:c,inheritance,standard-library
来源: https://codeday.me/bug/20190911/1803880.html