根据《C++ Primer 第五版》整理,支持C++11相关特性。
1. 概述
所有顺序容器都支持快速访问元素,但是其性能的差异在于:
l 添加、删除元素的代价
l 随机访问元素的代价
类型 | 随机访问 | 添加删除 | 备注 |
vector | 支持 | 在尾部之外添加较慢,删除较慢 | 线性存储 |
array | 支持 | 不能 |
|
string | 支持 | 在尾部插入快 | 类似于vector |
deque | 支持 | 在头尾插入很快 | 双端队列 |
list | 不支持 | 插入删除都很快 | 双向链表 |
forward_list | 不支持 | 插入删除都很快 | 单向链表 |
注:array不支持改变大小,不支持添加、删除元素;forward_list设计目标为达到手写单项链表的性能,所以不支持计算大小的size操作。
2. 选择
通常都是使用vector。以下是一些选择原则:
l 随机访问元素要求使用vector和deque。
l 在中间插入、删除元素,使用list或forward_list。
l 只在头尾插入、删除,选择deque。
3. 容器库
表3-1 容器操作 | |
构造 | |
C c; | 默认构造 |
C c1(c2); | 构造c2的拷贝 |
C c(b,e); | 迭代器b,e指定范围拷贝到c(array不支持) |
C c{a,b,c,…}; | 列表初始化 |
赋值于置换 | |
c1 = c2; | c1中元素替换为c2中的元素 |
c1 = {a,b,c,…}; | 将c1中的元素替换为类表元素(不支持array) |
a.swap(b); | 交换a和b的元素 |
swap(a,b); | 同上 |
大小 | |
c.size(); | 元素数目(forward_list不支持) |
c.max_size(); | 可保存的元素最大数目 |
c.empty(); | 容器是否存有元素(返回值为true或false) |
添加删除元素(array不支持,且在不同容器中,接口不同) | |
c.insert(argv); | 将argv拷贝到c |
c.emplace(inits); | 使用inits构造c中一个元素 |
c.erase(argv); | 删除指定元素 |
c.clear(); | 清空c,返回void |
==,!= | 判断是否相等 |
迭代器 | |
c.begin(),c.end(); | 返回指向容器收尾元素的迭代器(指针) |
c.cbegin(),c.cend(); | 返回常量指针迭代器 |
注:迭代器类型只包含*,->,==,!=,--,++等关系运算符,vector、string支持<,<=,>,>=;
常量迭代器只能读取,不能修改。
4. 定义与初始化
表4-1 六中定义、初始化方法 | |
C c; | array容器按系统默认值构造,其他则构造为空 |
C c1(c2); | 容器、元素类型必须相同,array容器还需要长度一致 |
c1 = c2; | |
C c(b,e); | 元素类型相容(基于迭代器指针的拷贝) |
C c{a,b,c,…}; | 元素类型相容。若为array容器,列表长度不大于array分配长度,且系统已默认值不全未初始化数据 |
c1 = {a,b,c,…}; |
接收容器的初始化必须要求容器类型和元素类型一致,而接收两个迭代器的初始化只需满足元素类型相容,初始化时会做相应的隐式转换。
例:
赋值置换要点:
l 不能以自身及自身子序列为自身赋值
l 交换swap函数调用完后,原来的元素地址没变,所以对元素引用的指针内容不变,只是属于了不同的容器。可以理解为容器名称交换了。
容器关系运算符操作要点:容器类型一致,元素类型相同,元素逐对比较。