Effective STL:1、容器

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_30534935/article/details/102726014

没错,STL 中有迭代器、算法和函数对象,但是对于大多数 C++ 程序员来说,最值得注意的还是容器。容器比数组功能更强大、更灵活。它们可以动态增长(和缩减),可以自己管理内存,可以记住自己包含了多少对象。它们限定了自己所支持的操作的复杂性。诸如此类的优点还有很多。不难理解它们为何如此受欢迎,因为相对于其竞争者,无论是来自其他库中的容器还是你自己编写的容器,其优越性是显而易见的。STL容器不是简单的好,而是确实很好。


本章讲述适用于所有 STL 容器的准则。随后几章将就特定类型的容器展开描述。本章内容包括:如何就你所面临的具体制约条件选择适当的容器类型;避免一种错误认知,即为一种类型的容器而编写的代码换了其他容器也能工作;对于容器中的对象,复制操作的重要性;当指针或 auto_ptr 被存放在容器中时会有什么样的困难;删除操作的细节;用定制的分配子能做什么以及不能做什么;是程序获得最高效率的窍门;以及在多线程环境中使用容器的一些考虑。


涉及的方方面面很多。别着急,饭要一口一口地吃。这些问题将分为几条,逐条下来,你一定会形成一些想法,并将这些想法应用到你正在编写的代码中。



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


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

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

非标准序列容器:slist 和 rope。

非标准的关联容器:hash_set、hash_multiset、hash_map、hash_multimap。



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


这些限制的根源在于,对不同类型的序列容器,使迭代器、指针和引用无效的规则是不同的。



第3条:确保容器中的对象拷贝正确而高效


STL 做了很多拷贝,但它总的设计思想是为了避免不必要的拷贝。

事实上,他总体的设计目标是为了避免创建不必要的对象。



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


empty 对所有的标准序列容器都是常数时间操作,而对一些 list 的实现,size 耗费线性时间。



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


通过使用区间成员函数,通常可以少写一些代码。

使用区间成员函数通常会得到意图清晰和更加直接的代码。



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


使用命名的迭代器对象与通常的 STL 程序风格相违背,但你或许觉得为了使代码对所有编译器都没有二义性,并且是维护代码的人理解起来更容易,这一代价是值得的。



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


STL 容器很智能,但没有智能到直到是否该删除自己所包含的指针的程度。

当你使用指针的容器,而其中的指针应该被删除时,为了避免资源泄漏,你必须用引用计数形式的智能指针对象代替指针,或者当容器被析构时手动删除其中的每个指针。



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


千万别创建包含 auto_ptr 的容器,即使你的 STL 平台允许你这样做也不行。



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


要有效的删除容器中的元素,除了调用 erase 之外还要做很多工作。

解决问题的最佳方法取决于如何识别要删除的对象、存储元素的容器类型,以及当删除时你想做什么。



第10条:了解分配子的约定和限制


你的分配子是一个模板,模板参数 T 代表你为它们分配内存的对象的类型。

提供类型定义 pointer 和 reference ,但是始终让 pointer 为 T*,reference 为 T&。

千万别让你的分配子拥有随对象而不同的状态。通常,分配子不应该有非静态的数据成员。

记住,传给分配子的 allocate 成员函数的是那些要求内存的对象的个数,而不是所需的字节数。同时要记住,这些函数返回 T* 指针,即使尚未拥有 T 对象呗构造出来。

一定要提供嵌套的 rebind 模板,因为标准容器依赖该模板。



第11条:理解自定义分配子的合理用法


只要你遵守了同一类型的分配子必须是等价的这一限制要求,那么,当你使用自定义的分配子来控制通用的内存管理策略的时候,或者在聚集成员关系的时候,或者在使用共享内存和其他特殊堆的时候,就不会陷入麻烦。



第12条:切勿对 STL 容器的线程安全性有不切实际的依赖


对于一个 STL 实现你最多只能期望:

多个线程是安全的。

多个线程对不同的容器做写入操作是安全的。

猜你喜欢

转载自blog.csdn.net/qq_30534935/article/details/102726014