本文主要是介绍Effective STL:第二部分 容器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第二部分 vector和容器
第十三条:vector和string优先于动态分配的数组
当你决定用new来分配内存时,将承担以下责任:
n 你必须确保以后会有人调用delete来删除所分配的内存,否则将导致资源泄露。
n 你必须确保调用了正确的delete形式。比如单个对象调用delete;分配了数组,则调用delete[]。
n 你必须确保只delete了一次。如果一次分配被多次delete,结果也是不确定的。
如果使用vector和string,则可以减少以上的担忧。
如果你使用的string是以引用计数来实现的,而又在多线程的环境中,可以考虑以下几种做法:
n 检查库实现,看看是否可以禁止引用计数。这种方法不可移植。
n 寻找或开发一个不适用引用计数的string实现。
n 考虑使用vector<char>而不是string,会丢失使用string的成员函数的机会,但可以通过stl算法实现。
第十四条使用reserve来避免不必要的分配。
Vector和的string的自动增长是这样实现的:
n 当容器容量不足时,分配一块大小为当前容量+max(当前容量,新增容量) 的新内存。大多数时候,都是每次以2的倍数增长,即容量需要扩张时,它们的容量加倍。
n 把容器的所有元素从旧的内存复制到新的内存。
n 析构掉旧内存中的对象
n 释放旧内存
因此,容器的自动增长是会很耗时的。使用reserve能避免容器不必要的重复分配。主要有两种方式:
n 若能确切知道或大概预计容器中最终会有多少元素,则可以使用reserve。
n 先预留足够大的空间,然后,当把所有数据都加入以后,去除多余的容量。可以考虑使用“swap技巧“(见17条)。
第十五条 注意string实现的多样性
几乎每个string实现都包含以下信息:
n 字符串的大小
n 用于存储该字符中的字符的内存的容量
n 字符串的值
n 它的分配子的一个拷贝,这个字段是可选的
n 对数的引用计数。
String的实现比咋看上去有更多的自由度;同样明显的是,不同的实现以不同的方式利用了这种设计上的灵活性。这些区别总结如下:
n String的值可能会被引用计数
n String对象大小的范围可以是一个char*指针的大小的1-7倍
n 创建一个新的字符串值可能需要零次,一次或两次动态分配内存
n String对象可能共享,也可能不共享其大小和容量信息。
n String可能支持,也可能不支持针对单个对象的分配子
n 不同的实现对字符内存的最小分配单位有不同的策略。
其实stl也有很多实现版本,每个版本的string实现都是不太一样的。以后会再找一个string实现源码具体分析。
第十六条了解如何把vector和string数据传给旧的API
Vector和string的数据传送到旧API方式:
n vector保证和数组具有同样的布局,可以直接把vector中的数据当做数组来对待。&V[0]即数组的首地址指针。反之亦然,可以将数组元素直接复制到vector的内存地址。
n String提供c_str()函数来返回一个指向字符串的值的指针,且可用于C。因为string中的数据不一定是存储在连续的内存中,而且不一定以空字符结尾。所以不能随便修改指针指向内存的值,特意用显式调用作为提醒。
n 对于其他类型的stl容器,可以将数据先拷贝到vector,用vector作为中介与旧API相互传送数据
这篇关于Effective STL:第二部分 容器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!