background image

第 1

 

章 容器

第 1 条:慎重选择容器类型。

标准 STL 序列容器:vector、string、deque 和 list。

标准 STL 关联容器:set、multiset、map 和 multimap。

非标准序列容器 slist 和 rope。slist 是一个单向链表,rope

本质上是一 重型 string。

非标准的关联容器 hash_set、hase_multiset、hash_map 和 hash_multimap。
vector<char> 作为 string 的替代。(见第 13 条)
vector 作为标准关联容器的替代。(见第 23 条)

几种标准的非 STL 容器,包括数组、bitset、valarray、stack、queue 和 priority_queue。

你是否关心容器中的元素是如何排序的?如果不关心,选择哈希容器.

容器中数据的布局是否需要和 C 兼容?如果需要兼容,就只能选择 vector。(见第 16

条)

元素的查找速度是否是关键的考虑因素?如果是,就要考虑哈希容器、排序的 vector

和标准关联容器-或许这就是优先顺序。

对插入和删除操作,你需要事务语义吗?如果是,只能选择 list。因为在标准容器中,

只有 list 对多个元素的插入操作提供了事务语义。

deque 是唯一的、迭代器可能会变为无效(插入操作仅在容器末尾发生时,deque 的迭

代器可能会变为无效)而指向数据的指针和引用依然有效的标准 STL 容器。

第 2 条:不要试图编写独立于容器类型的代码。

如果你想编写对大多数的容器都适用的代码,你只能使用它们的功能的交集。不同的容器
是不同的,它们有非常明显的优缺点。它们并不是被设计用来交换使用的。

  你无法编写独立于容器的代码,但是,它们(指客户代码)可能可以。

第 3 条:确保容器中的对象拷贝正确而高效。
copy in,copy out,是 STL 的工作方式,它总的设计思想是为了避免不必要的拷贝。使拷贝

动作高效并且防止剥离问题发生的一个简单办法是使容器包含指针而不是对象。

第 4 条:调用 empty 而不是检查 size()是否为 0。

  理由很简单:empty 对所有的标准容器都是常数时间操作,而对一些 list 的实现,
size 耗费线性时间。

第 5 条:区间成员函数优先于与之对应的单元素成员函数。

区间成员函数写起来更容易,更能清楚地表达你的意图,而且它们表现出了更高的效率。

第 6 条:当心 C++编译器最烦人的分析机制。

把形参加括号是合法的,把整个形参的声明(包括数据类型和形参名字)用括号括

起来是非法的。

第 7 条:如果容器中包含了通过 new 操作创建的指针,切记在容器对象析构前将指

针 delete 掉。

STL 很智能,但没有智能到知道是否该删除自己所包含的指针所指向的对象的程度。

为了避免资源泄漏,你必须在容器被析构前手工删除其中的每个指针,或使用引用计数
形式的智能指针(比如 Boost 的 sharedprt)代替指针。

第 8 条:切勿创建包含 auto_ptr 的容器对象。

拷贝一个 auto_ptr 意味着改变它的值。例如对一个包含 auto_ptr 的 vector 调用 sort 排序,结

果是 vector 的几个元素被置为 NULL 而相应的元素被删除了。

第 9 条:慎重选择删除元素的方法。

要删除容器中指定值的所有对象:

如果容器是 vector、string 或 deque,则使用 erase-remove 习惯用法。
SeqContainer<int> c;
c.erase(remove(c.begin(),c.end(),1963),c.end());

如果容器是 list,则使用 list::remove。