c++顺序容器

 

1. 几种顺序容器的比较

容器 本质 特点 适用范围
vector 可变大小数组 连续存储,快速随机访问,除尾部插入删除慢 默认使用
deque 双端队列 快速随机访问,除首尾插入删除慢 两端都需要添加删除元素
list 双向链表 不支持随机访问(只能遍历),插入删除迅速,额外内存开销大 需要中间插入元素
forward_list 单向链表 同list,只支持单向顺序访问 同上
array 固定大小数组 与内置数组类似,更安全易用 固定大小数组
string 类vector,保存字符 连续 存字符

 选用vector/deque还是list/forward_list取决于访问操作和插入/删除操作的相对比例。

访问更频繁,选用vector/deque。若插入/删除频繁,选用list/forward_list。

小技巧:如果必须在中间位置插入元素,之后大都为访问操作,可以在输入阶段使用list,输入完成拷贝到vector。

 

2. vector、string对象的存储

为支持快速随机访问,vector将元素连续存储。若每次存储都申请一次内存分配,每删除一个元素进行内存释放,会大大降低程序的运行性能。所以vector和string的实现通常会分配比需求更大的空间,容器预留这些空间作为备用,这样就不需要每次添加新元素都重新分配内存了。

当然,这样做也有缺点,即每次重新分配内存时都要移动所有的元素。但使用这种策略,使得扩张操作通常比list和deque还要快。

为此,容器大小管理操作里只有vector和string有c.capacity(),与其他容器共通的为c.size()。

c.capacity()含义为分配的空间大小(即不分配新内存空间前最多能保存的元素大小)。

c.size()含义为实际已经保存元素的数量。所以有c.capacity() >= c.size()。

 

3. 容器操作可能导致迭代器失效

向容器中添加或删除元素可能会使指向容器元素的指针、引用或迭代器失效。

添加或删除元素:

对于vector和string,插入或删除位置之后元素的指针、引用和迭代器都失效,之前的仍有效。若需要重新分配内存,指向容器的指针、引用和迭代器将全部失效。

对queue,插入或删除除首尾的任何位置都会使指针、引用和迭代器失效。

对两list,没影响。

为避免失效引起的问题,可使用insert或erase这种返回迭代器的操作更新迭代器。

不应在循环前保存end()返回的迭代器,必须每次插入操作后重新调用end()。

错误示例:

auto begin = v.begin()
     end = v.end();
while (begin != end)
{
    //插入操作,省略
}

正确示例:

while (begin != v.end())//重新计算end
{
    //插入操作,省略
}

你可能感兴趣的:(C++)