元素在顺序容器中的顺序与其加入容器时的位置相对应。
关联容器中的元素位置由元素相关联的关键字值决定
所有容器类都共享公共的接口,不同的容器按照不同的方式对其进行拓展。
- 一个容器就是一些特定类型对象的集合。顺序容器为程序员提供了控制元素存储和访问顺序的能力。
- 访问顺序不依赖于元素的值,而是与元素加入容器时的位置相对性。
- 标准库提供了三种容器适配器,分别为容器操作定义了不同的接口,来与容器类型适配。
1.1 顺序容器概览
所有的顺序容器都提供了快速访问元素的能力,但是这些容器在以下方面都有不同的性能折中:
- 向容器中添加或者从容器中删除元素的代价
- 非顺序访问元素的代价
顺序容器类型 |
|
|
|
array |
固定大小数组 |
支持快速随机访问 |
不能添加或者删除 |
vector |
可变大小数组 |
支持快速随机访问 |
在尾部之外的位置插入或者删除元素可能很慢 |
string |
与vector相似的容器,但是专门用来保存字符 |
支持快速随机访问 |
在尾部插入和删除速度很快 |
deque |
双端队列 |
支持快速随机访问 |
在头尾位置插入和删除速度很快 |
list |
双向链表 |
支持双向顺序访问 |
在list中任何位置进行插入/删除操作速度都很快 |
forward_list |
单向链表 |
只支持单向顺序访问 |
在链表中任何位置进行插入/删除操作速度都很快 |
- 除了固定大小的array外,其他容器都提供高效灵活的内存管理,我们可以添加和删除元素。
- string和vector将元素保存在连续的内存空间中,根据元素下标来计算地址是非常快速的,但是在这两种元素中间位置添加或者删除元素就会非常耗时。
- list和forward_list两个容器的设计目的是另容器的中间位置添加或者删除元素都很快,最为代价这两个容器不支持随机访问。
- deque支持快速随机访问,与string和vector一样,在deque的中间位置添加或者删除元素的代价很高,在两端添加和删除元素很快。
- forward_list和array是C++新增的类型,与内置数组相比,array是一种更安全,更容易使用的数组类型。
1.2 容器库概览
- 有些操作是所有容器类型都提供的
- 另外一些只支持顺序容器或者关联容器或者无序容器
- 还有一些操作只适用于一小部分容器
一般来说,每个容器都定义在一个与类型名相同的头文件中
- queue定义在queue
- list定义在list
- 以此类推
顺序元素对保存的元素类型的限制
- 顺序元素几乎可以保存任意类型的元素,但是某些容器操作对元素类型有其特殊要求。
- 可以为不支持特定操作的类型定义容器,这种情况下只能使用那些没有特殊要求的容器操作。
容器操作 |
|
|
类型别名 |
|
|
iterator |
此容器类型 |
迭代器类型 |
const_iterator |
可以读取元素,但是不能修改元素 |
迭代器类型 |
size_type |
无符号整数类型 |
足以保存此种容器类型最大可能容器的大小 |
difference_type |
带符号整数类型 |
足以保存两个迭代器之间的距离 |
value_type |
元素类型 |
|
reference |
元素的左值类型,与value_type&含义相同 |
|
const_reference |
元素的const左值类型,与const value_type&含义相同 |
|
构造函数 |
|
C c; |
默认构造函数 |
C c1(c2); |
构造c2的拷贝c1 |
C(b,e) |
构造c,将迭代器b和e制定的范围内的元素拷贝到c |
C c{a,b,c…} |
列表初始化c |
赋值与swap |
|
c1=c2 |
将c1中的元素替换为c2中的元素 |
c1={a,b,c…} |
将c1中的元素替换为列表中的元素(不适用于array) |
a.swap(b) |
交换a与b中的元素 |
swap(a,b) |
与a.swap(b)等价 |
大小 |
|
c.size() |
c中元素的数目(不支持forword_list) |
c.max_size() |
c可保存的最大元素数目 |
c.empty() |
若c中存储了元素,返回false |
添加删除元素 |
在不同的容器中中这些接口都不同 |
c.insert(args) |
将args中的元素拷贝进c |
c.emplace |