条目二《不要编写独立于容器类型的代码》
主要是讲了STL的各个容器就是一个个已经泛化的抽象实体,每种容器就是一个容器类型,他们都有属于自己的特点,我们不应该在现有的容器类型外,基于现有的容器类型混合和裁剪各个容器的所属特点来再次泛化一个通用的容器类型。
这么做是不可取的。我个人觉得条目二是针对“中牛们🐮”说的,因为“小牛们”只会用STL,而“大牛们”肯定会清晰的明白STL设计为一个个单独的容器类型的目的。
在我看来,STL设计的目的不是为了设计一个通用的泛化容器,而是设计一个个不同使用领域和各自具有自己使用特点的泛化容器。
容器类型的不同而表现出不同的原型和语义。
我们应该针对单个容器类型的泛化做文章,而不是把容器的概念再次泛化,自己new一种二次封装泛化的新容器类型。为什么要禁止或者说不提倡这种想法,做法呢?下面从STL各个容器的特点来说明。
-
1.根据内存是否连续,容器提供的访问方式不一样。基于连续内存的容器提供了随机访问迭代器,提供push_front()或push_back()。基于节点存储的容器提供了双向迭代器,提供对数时间的lower_bound(),upper_bound()等成员函数。
-
2.向序列容器中插入对象时,该对象位于被插入的位置处;而向关联容器插入对象时,内部会把对象插入到合适的位置,因为关联容器底层是平衡树实现的,平衡树在插入时会动态维护自身的平衡而调整数据的插入位置。
-
3.当带有一个迭代器参数的erase作用于序列容器时,会返回一个新的迭代器,但当它作用于关联容器时则没有返回值。这样在编写代码的时候是有区别的。
-
4.编写通用的容器,比如通用的序列容器( vector,deque,list)(关联容器也是一样),只能是取它们的交集函数功能,因为是通用,通用代表对于它们都应该是适用的,所以只能是交集功能和思想囖。《这些限制的根源在于,对不同类型的序列容器,使迭代器、指针和引用无效的规则是不同的》
基于以上的问题,所以通用的容器类型是毫无意义的,限制太多了,往往会得不偿失。
但是有时候,在实现完需求后,过一段时间会觉得现有的容器类型不太符合需求,需要换另外一种容器。这种需求给别人(客户)“无变”的感觉的做法是:从一种容器类型转到另一种,你可以使用常规的方式来实现这种转变:使用封装技术。最简单的方式是通过对容器类型和其迭代器类型使用类型定义。
封装容器成class的好处是:
- 1.代码可读性提高
- 2.代码封装,提高代码复用性
- 3.封装容器,方便后期替换另外一种容器
- 4.私有化底层实现,封装细节,为客户代码考虑好各种兼容性。