list<int> ilist(10);
// 空容器:*ilist.begin() 无法解引用
// 空容器:back()、front() 操作,未定义
if(!ilist.empty())
{
list<int>::reference val = *ilist.begin();
list<int>::reference val2 = ilist.front();
list<int>::reference last = *--ilist.end();
list<int>::reference last2 = ilist.back();
}
c.back() | 返回容器c 的最后一个元素的引用. c 为空,操作未定义 |
---|---|
c.front() | 返回容器c 的第一个元素的引用. c 为空,操作未定义 |
c[n] | 返回下标为n 的元素的引用 如果 n<0 或者 n>=c.size(), 操作未定义 只适用于 vector 和 deque 容器 |
c.at(n) | 返回下标为 n 的元素的引用。如果下标越界,操作未定义 只适用于 vector 和 deque 容器 |
at() 成员函数,类似于下标操作,如果下标无效, at 函数会抛出 out_of_range 异常
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 容器 |
#include <algorithm>
list<string> websiteList;
websiteList.push_back("google");
websiteList.push_back("baidu");
websiteList.push_back("taobao");
string searchStr("google");
list<string>::iterator iter = find(websiteList.begin(), websiteList.end(), searchStr);
if(iter!= websiteList.end())
{
websiteList.erase(iter);
}
// 同下:websiteList.erase(websiteList.begin(), websiteList.end());
websiteList.clear();
c1 = c2 | 删除容器 c1 的所有元素,然后将 c2 的元素复制给 c1。 c1 和 c2 的类型必须相同 |
---|---|
c1.swap(c2) | 交换 c1、c2 的内容,调用成功后,c1 存放的是 c2 原来的元素,c2 存放的是 c1 原来的元素 c1 和 c2 的类型必须完全相同。此函数执行速度通常要比,将c2 复制到 c1 的操作快 |
c.assign(b, e) | 重设c 的元素,将迭代器 b 和 e 标记的范围内所有的元素复制到c 中。 b、e 必须都不是指向 c 中元素的迭代器。因为该函数是先删除容器中原来存储的所有元素 |
c.assign(n, t) | 重设 c , 存储 n 个值为 t 的元素 |
list<string> slist1;
slist1.push_back("google");
slist1.push_back("baidu");
list<string> slist2;
// 等效于: slist2 = slist1;
// 但是,如果 list<char *> slist1,则,只能使用 assign() 操作
slist2.assign(slist1.begin(), slist1.end());
// 等效于:
// slist1.clear();
// slist1.insert(slist1.begin(), 10, "test");
slist1.assign(10, "test");
// 此操作不会导致迭代器失效
// 如,list<string>::iterator iter = slist1.begin();
// 那么,执行 swap 之后, iter 指向 slist2.begin()
slist1.swap(slist2);
vector 容器,为支持快速的随机访问, vector 容器的元素以连续的方式存放
标准库会以最小的代价来连续存储元素
为了使 vector 容器实现快速的内存分配,其实际分配的容量要比所需的空间多一些。
分配的额外内存容量,因库的不同实现而不同。其性能非常好。
大部分应用下,使用 vector 是最好的
list 容器中,添加一个新元素,标准库只需要创建元素,
然后,将其连接在已经存在的链表中,而不必重新分配内存,也不必复制任何已存在的元素
capacity 和 reserve 成员
vector<int> ivec;
cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():0
// ivec.capacity():0
for(vector<int>::size_type ix = 0; ix != 15; ++ix)
ivec.push_back(ix);
cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():15
// ivec.capacity():19
ivec.clear();
ivec.reserve(25);
while(ivec.size() != ivec.capacity())
ivec.push_back(88);
cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():25
// ivec.capacity():25
ivec.push_back(99);
cout << "ivec.size():" << ivec.size() << endl
<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():26
// ivec.capacity():37
容器的选用
vector 和 deque 都支持快速随机访问,vector ,执行插入和删除操作时,如果不是容器末尾进行操作,那么它的开销较大
deque 容器,双端队列,在容器首、尾 的插入和删除操作都非常快。
deque 容器中,首、尾,插入元素操作,不会使任何迭代器失效
而在首、尾 删除元素,则会使指向被删除元素的迭代器失效。
任何其他位置的插入、删除,会使指向该容器元素的所有迭代器失效。
list 容器可以在任意位置实现快速的插入和删除,但是,随机访问的开销较大
list 容器表示不连续的内存区域,允许向前或向后逐个遍历元素,
访问 list 容器中的某个元素,需要遍历相关的所有其他元素
在 list 容器的元素之间移动的唯一方法是顺序跟随指针,
比如,从5号元素,移动到15号元素,必须遍历5-15之间的所有元素