文章目录
STL六大组件
- 容器
- 迭代器
- 算法
- 仿函数
- 适配器
- 空间配置器
容器
参考https://blog.csdn.net/qq_43313035/article/details/89600276
迭代器
-
容器与算法之间的连接,是所谓的“泛型指针”
-
迭代器是一种智能指针,智能指针定义为存储指向动态分配对象指针的类,迭代器封装了指针的同时,还对指针的一些基本操作如*、->、++、==、!=、=进行了重载,使其具有了遍历复杂数据结构的能力,其遍历机制取决于所遍历的数据结构。如operator++运算符,对于数组就是普通的++下一个元素,对于链表则是先去next,再取元素。
-
每一种容器型都必须提供自己的迭代器。事实上每一种容器都将其迭代器以嵌套的方式定义于内部
-
定义和初始化
vector<int>::iterator it;//定义一个名为 it的迭代器变量
vector<int> vec;//定义一个名为vec的向量容器
it=vec.begin();//将it初始化为指向容器中的第一个元素
it=vec.end(); //将it初始化为指向容器最后一个元素的下一个位置,此时it称为超出末端迭代器。
- 常用操作
操作 | 作用 |
---|---|
++iter | 给iter加1,使其指向容器的下一个元素 |
iter++ | 给iter加1,使其指向容器的下一个元素 |
–iter | 给iter减1,使其指向容器的前一个元素 |
iter– | 给iter减1,使其指向容器的前一个元素 |
iter1==iter2 | 比较两个迭代器是否相等 |
iter1!=iter2 | 比较两个迭代器是否不相等 |
*iter | 对iter进行解引用,返回迭代器iter指向的元素的引用 |
iter->ma | 对iter进行解引用,获取指定元素中名为ma的成员。等效于(*iter).ma |
- const_iterator
该类型的迭代器只能读取容器中的元素,不能通过迭代器改变容器中元素的值。
举例
vector<int> vec;
for (vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++iter)
{
cout << *it << endl;//ok
}
for (vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++iter)
{
*it = 0; //error
}
- const_iterator 和 const iterator
- const iterator对迭代器进行声明,必须对迭代器进行初始化,并且一旦初始化后就不能修改其值。(类似于常量指针和指针常量的关系)
vector<int> vec(5);
const vector<int>::iterator it = vec.begin();
*it = 0;//ok
it++; //error
迭代器失效
由于一些对容器的操作如删除元素或移动元素等会修改容器的内在状态,这会使得原本指向被移动元素的迭代器失效,也可能同时使其他迭代器失效。使用无效的迭代器是没有定义的,可能会导致和使用悬垂指针相同的问题。
- vector迭代器失效
- 当执行erase()后,指向删除节点的迭代器失效,指向删除节点之后的全部迭代器也失效
- 当push_back()后,end操作返回的迭代器肯定失效。
- 当push_back()一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
- 当push_back()一个元素后,如果空间未重新分配,指向插入位置之前的元素的迭代器仍然有效,但指向插入位置之后元素的迭代器全部失效。
举例
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i);
}
vector<int>::iterator it;
for (it=vec.begin(); it != vec.end(); it++)
{
if (*it>5)
{
vec.erase(it);
}
}
for (it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
修改代码后的结果
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> vec;
for (int i = 0; i < 10; ++i)
{
vec.push_back(i);
}
vector<int>::iterator it;
for (it=vec.begin(); it != vec.end(); )
{
if (*it>5)
{
it=vec.erase(it);//迭代器进行更新
}
else
{
++it;
}
}
for (it = vec.begin(); it != vec.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
-
deque迭代器失效
-
对于deque,插入到除首尾位置之外的任何位置都会导致迭代器、指针和引用都会失效,但是如果在首尾位置添加元素,迭代器会失效,但是指针和引用不会失效
-
如果在首尾之外的任何位置删除元素,那么指向被删除元素外其他元素的迭代器全部失效
-
在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。
-
关联容