一、容器定义的类型的别名
所有容器都提供的类型别名 | |
size_type | 无符号整型,足以存储容器类型的最大可能容器长度 |
iterator | 容器的迭代器类型 |
const_iterator | 容器的只读迭代器类型 |
reverse_iterator | 按逆序寻址元素的迭代器类型 |
const_reverse_iterator | 元素的只读逆序迭代器 |
difference_type | 足够存储两个迭代器差值的有符号整型,可为负数 |
value_type | 元素类型 |
reference | 元素的左值类型,是value_type&的同义词 |
const_reference | 元素的常量左值类型,等效于constvalue_type& |
二、使用方法
三、容器的成员
容器的begin和end成员 | |
c.begin() | 返回一个迭代器,它指向容器c的第一个元素 |
c.end() | 返回一个迭代器,它指向容器c的最后一个元素的下一位置 |
c.rbegin() | 返回一个逆序迭代器,它指向容器c的最后一个元素 |
c.rend() | 返回一个逆序迭代器,它指向容器c的第一个元素前面的位置 |
四、容器的添加操作
在顺序容器中添加元素的操作 | |
c.push_back() | 在容器c的尾部添加值为t的元素。返回void类型 |
c.push_front() | 在容器c的前端插入值为t的元素。返回void类型。 只适用于list和deque容器类型。 |
c.insert(p,t) | 在迭代器p所指向的元素前面插入值为t的新元素,返回指向新添加元素的迭代器。 |
c.insert(p,n,t) | 在迭代器p所指向的元素前面插入n个值为t的新元素,返回void |
c.insert(p,b,e) | 在迭代器p所指向的元素前面插入迭代器b和e标记的范围内的元素,返回void。 |
emplace操作是C++11新特性,新引入的的三个成员emlace_front、empace 和 emplace_back,这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。
两者的区别
当调用insert时,我们将元素类型的对象传递给insert,元素的对象被拷贝到容器中,而当我们使用emplace时,我们将参数传递元素类型的构造函,emplace使用这些参数在容器管理的内存空间中直接构造元素。
例子
假定d是一个Date类型的容器。
//使用三个参数的Date构造函数,在容器管理的内存空间中构造新元素。
d.emplace_back(“2016”,”05”,”26”);
//错误,push_back没有这种用法
d.push_back(“2016”,”05”,”26”);
//push_back()创建一个临时对象,然后将临时对象拷贝到容器中
d.push_back(Date(“2016”,”05”,”26”));
通过例子发现,使用C++11新特性emplace向容器中添加新元素,在容器管理的内存空间中构造新元素,与insert相比,省去了构造临时对象,减少了内存开销。
Note
emplace函数在容器中直接构造元素,传递给emplace函数的参数必须与元素类型的构造函数相匹配。
五、容器的大小操作
所有容器都提供的大小操作 | |
c.size() | 返回容器c中的元素个数。返回类型为c::size_type |
c.max_size() | 返回容器c可容纳的最多元素个数,返回类型为c::size_type |
c.empty() | 返回标记容器大小是否为0的布尔值 |
c.resize(n) | 调整容器c的长度大小,使其能容纳n个元素,如果n<c.size(), 则删除多出来的元素;否则,添加采用值初始化的新元素 |
c.resize(n,t) | 调整容器c的长度大小,使其能容纳n个元素。所有新添加的元素值都为t |
六、访问容器的操作
访问顺序容器内元素的操作 | |
c.back() | 返回容器c的最后一个元素的引用,如果c为空,则该操作未定义 |
c.front() | 返回容器c的第一个元素的引用,如果c为空,则该操作未定义 |
c[n] | 返回下标n的元素的引用,如果n<0或n>=c.size(),则该操作未定义 只适用于vector和deque容器 |
c.at(n) | 返回下标为n的元素的引用,如果下标越界,则该操作未定义 只适用于vector和deque容器 |
七、删除操作
删除顺序容器内元素的操作 | |
c.erase(p) | 删除迭代器p所指向的元素 返回一个迭代器,它指向被删除元素后面的元素。如果p指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。 如果p本身就是指向超出末端的下一位置的迭代器,则该函数未定义 |
c.erase(b,e) | 删除迭代器b和e所标记的范围内所有的元素 返回一个迭代器,它指向被删除元素段后面的元素。 如果e本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置 |
c.clear() | 删除容器c内的所有元素。返回void |
c.pop_back() | 删除容器c的最后一个元素。返回void。如果c为空容器, 则该函数未定义 |
c.pop_front() | 删除容器c的第一个元素。返回void。如果c为空容器,则该函数未定义 只适用于list或deque容器 |
八、赋值和swap操作
顺序容器的赋值与swap操作 | |
c1= c2 | 删除容器c1的所有元素,然后将c2的元素复制给c1。 c1和c2的类型(包括容器类型和元素类型)必须相同 |
c.assign(b,e) | 重新设置c的元素:将迭代器b和e标记的范围内所有的元素复制到c中。b和e必须不是指向c中元素的迭代器 |
c.assign(n,t) | 将容器c重新设置为存储n个值为t的元素 |
c1.swap(c2) | 交换内容:调用完该函数后,c1中存放的是c2原来的元素,c2中存放的则是c1原来的元素。c1和c2的类型必须相同。 该函数的执行速度通常要比将c2复制到c1的操作快 |
九、vector属性
功能 | |
capaticy | 获取容器在需要重新分配空间之前,能够存储的元素总数 |
size | 目前存储的元素个数 |
reserve | 还剩余多少个位置空间 |
十、容器的选择
理论情况下:vector容器都是最佳的容器
十一、容器的适配器
容器适配器是让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现
比如,栈适配器可以让任何一种顺序容器以栈的方式工作
1、适配器有 stack,priority_queue,stack
适配器 | 默认所基于容器 |
stack | 默认是deque,可以建立在vector,list,或者deque |
queue | 默认是deque,只能是list |
priority | vector,只能是vector或queue |
2、适配器通用的操作和类型
size_type | 一种类型,足以存储此适配器类型的最大对象长度 |
value_type | 0 |
container_type | 基础容器类型,适配器在此容器类型上实现 |
Aa; | 创建一个空适配器,命名为a |
Aa(c); | 创建一个名为a的新适配器,初始化为c的副本 |
关系操作符 | 所有的适配器都支持全部关系操作符:==,!=,<,<=,>,>= |
3、栈适配器
s.empty() | 如果栈为空,则返回true,否则返回false |
s.size() | 返回栈中元素的个数 |
s.pop() | 删除栈顶元素,但不返回其值 |
s.top() | 返回栈顶元素,但不删除该元素 |
s.push(item) | 再栈顶压入元素 |
4、队列和优先队列
队列和优先级队列支持的操作 | |
q.empty() | 如果队列为空,则返回true,否则返回false |
q.size() | 返回队列中元素的个数 |
q.pop() | 删除队首元素,但不返回其值 |
q.front() | 返回队首元素,但不删除该元素 该操作只适用于队列 |
q.back() | 返回对尾元素,但不删除该元素 该操作只适用于队列 |
q.top() | 返回具有最高优先级的元素值,但不删除该元素 该操作只适用于优先级队列 |
q.push(item) | 对于queue,在队尾插入一个新的元素, 对于priority_queue,在基于优先级的适当位置插入新元素 |