迭代器简介
- 迭代器是一种遍历容器内元素的数据类型。(这种数据类型有点像指针,可以将迭代器理解为是用来指向容器内的某个元素的)
string可以用“[ ]”来访问string字符串内的字符,vector也可以通过“[ ]”来访问vector中的元素。但C++中一般采用迭代器来访问它们。除了vector容器外,C++标准库中还有好几种其他种类的容器(如:list、map等),均可使用迭代器来访问它们。string不是容器,但也支持用迭代器来遍历。
通过迭代器,可以读取容器中的元素值,修改容器中某个迭代器所代表(指向)的元素值。此外,迭代器可以像指针一样——通过
++、- -等运算从容器中的一个元素移动到另一个元素。
注:有很多容器并不支持“[ ]”来访问,但容器都支持迭代器来访问。
举例说明:
vector<int> myvec = {10,20,30,40};
vector<int>::iterator myiter // 定义了一个迭代器myiter;
iterator是每个容器里面都定义了的一个成员(类型名),这个名字是固定的。
迭代器begin/end 、反向迭代器rbegin/rend
每一种容器(如vector)都定义了一个叫begin()的成员函数和一个叫end()的成员函数,这两个成员函数正好用来返回迭代器类型。
-
begin() 如果容器中有元素,返回的迭代器指向容器中的第一个元素。
myiter = myvec.begin() // 相当于myiter代表着元素myvec[0] -
end() 返回的迭代器指向的并不是末端元素,而是末端元素的后面。
myiter = myvec.begin() // 指向末端元素后面,该元素并不存在 -
如果容器为空,则begin()返回的迭代器和end()返回的迭代器相同。

如果想从后面往前遍历一个容器,可以使用反向迭代器。即使用rbegin()成员函数和rend()成员函数。
-
rbegin() 返回一个反向迭代器,指向容器中最后一个元素。
-
rend() 返回一个反向迭代器,指向容器中第一个元素前面的位置。

const_iterator 迭代器
const表示常量,其值不能改变。这里的值不能改变指的是迭代器指向的元素值不能改变,并不表示迭代器本身不能改变,该迭代器本身是能改变的。
该迭代器只能从容器中读取元素,不能通过该迭代器改变容器中元素的值。所以,
const_iterator更像一个常量指针,而iterator迭代器是能读能写的。
const vector<int>myiv = { 10,20,30,40 };
vector<int>::const_iterator myiter;
for ( myiter = myiv.begin(); myiter != myiv.end(); myiter++)
{ //这里的begin()和end()返回的是const_iterator
//返回的是iterator还是const_iteraor,取决于对象容器是否是const对象
cout << *myiter << endl;
}
C++11引入了两个新的成员函数
cbegin()和cend()。不管容器是否是常量容器,cbegin()和cend()返回的都是const_iterator。
迭代器失效
for循环中,增删容器中的元素都会导致迭代器失效。如果在一个使用了迭代器的循环中插入元素到容器中,那么只插入一个元素后就应该立即跳出循环体。
举例:vector容器常用操作和内存释放
存在一个配置项:
ServerName = 1区
ServerID =10000
#include<iostream>
#include<vector>
using namespace std;
struct conf
{
char itemname[40];
char itemcontent[100];
};
char* getinfo(vector<conf*>& conflist, const char* pitem)
{
for (auto pos = conflist.begin(); pos != conflist.end(); pos++)
{
if ( _stricmp( (*pos)->itemname , pitem ) == 0 )
{
return ( *pos) -> itemcontent;
}
}
return nullptr;
}
int main(void)
{
conf* p_conf1 = new conf;
strcpy_s(p_conf1->itemname, sizeof(p_conf1->itemname), "ServerName");
strcpy_s(p_conf1->itemcontent, sizeof(p_conf1->itemcontent), "1区");
conf* p_conf2 = new conf;
strcpy_s(p_conf2->itemname, sizeof(p_conf2->itemname), "ServerID");
strcpy_s(p_conf2->itemcontent, sizeof(p_conf2->itemcontent), "10000");
vector<conf*> conflist;
conflist.push_back(p_conf1);
conflist.push_back(p_conf2);
char* p_tmp = getinfo(conflist, "ServerName");
//char* p_tmp = getinfo(conflist, "ServerID");
if (p_tmp != nullptr)
{
cout << p_tmp << endl;
}
//要释放内存,自己new就要自己delete,否则会造成内存泄漏
vector<conf*>::iterator pos;
for (pos = conflist.begin(); pos != conflist.end(); pos++)
{
//这里并没有破坏迭代器,因为没有往conflist里增加或删除元素,
//只是删除迭代器里元素所指向的由我们自己分配的内存
delete (*pos);
}
//.clear()这个可以不要,因为容器里的内容,在容器失效后系统会自动释放
conflist.clear();
return 0;
}
本文介绍了C++中的迭代器概念,作为遍历容器元素的工具,迭代器支持读取和修改元素值,并可通过++、--操作移动。文章通过示例展示了如何使用begin()和end()获取迭代器,以及反向迭代器rbegin()和rend()的用法。还提到了const_iterator用于只读访问,以及迭代器在插入和删除元素后的失效问题。最后,通过一个示例展示了在vector容器中使用迭代器查找和释放内存的操作。
889

被折叠的 条评论
为什么被折叠?



