deque容器在逻辑结构上跟vector容器非常相似,唯一的不同就是deque容器双向增长,在开头和结果插入删除元素都同样高效。但是在内部的实现结构上跟vector容器大相径庭,deque容器的元素并不是分布在连续的内存空间中,而是分为多个不同的内存块,第一内存块和最后一个内存块在增长方向上刚好相反。
1 deque容器的能力
和vector容器相比,deque容器有下面一些能力特征:
- 在容器开头和结尾插入和删除元素都同样高效。
- deque容器的内部结构跟vector容器不同,不是连续的平面结构,所以一般来说对deque容器元素的访问和iterator的移动操作跟vector相比有些缓慢。
- 因为deque容器的内部结构是由多个不同的内存块组成,所以deque的迭代器(iterator)不再可能是普通的指针,而是一种进行了封装的智能指针。
- 因为deque容器的内部结构是由多个不同的内存块组成,所以对于一些对内存块大小有限制的系统,deque容器容纳的最大元素数目可能要比vector多。也就是说max_size()的返回值可能比较大。
- deque容器没有提供对自身的capacity进行的控制的外部接口,对内存的管理完全由自身负责。除了在容器开头和结尾插入和删除元素外,其他的插入和删除操作都会使对应的元素引用、指针和迭代器失效。因为deque容器的内部结构是由多个不同的内存块组成,所以在插入和删除操作上通常要比vector高效,因为不同移动所有的元素。
- deque容器的内存块当不再使用时,可能会被释放掉,所以跟vector容器的单项增长不同,deque容器的内存大小会缩减。但什么时机释放不再使用的内存块,决定于具体的实现。
- 跟vector容器相同,在中间插入和删除元素时效率较低。
- 跟vector容器相同,deque的iterator也是随机访问迭代器。
综上所述,当下列需求吻合时,你应该选择deque容器:
- 你需要在开头和结尾两个方向操作(插入、删除)元素。
- 你不需要引用(reference)容器中的元素。
- 你需要容器所占用的内存空间自动调整,特别是自动释放内存。
2 deque容器的操作
deque容器的操作接口跟vector容器极为相似,区别之处在以下两点:
- deque容器不提供对capacity进行控制的接口(capacity()和reserve()函数)。
- deque容器提供了在容器开始位置操纵元素的接口push_front()和pop_front()。
对于deque容器,仍然需要注意的两点是:
- 对于随机元素访问操作符at(), [], front(), back(), 除了at()进行有效性检查外,其它操作符都不进行范围有效性检查,所以在使用时要特别小心。
- deque容器的插入和删除元素操作都有可能导致内存的重新分配,因此除了在容器开头和结尾插入删除元素外,其它时机都会使对应的元素引用、指针和迭代器失效,要特别注意。
3 deque容器的异常处理
deque容器对异常处理的支持跟vector容器基本相同,额外的push_front()和pop_front()接口行为分别对照push_back()和pop_back()接口。c++标准库提供了下面的说明:
- 如果使用push_front()或者push_back()插入元素时发生了异常,保证对原有元素没有影响,容器保持原状。
- pop_front()和pop_back()不抛出任何异常。