目录
1.文章的前续
昨天的文章我们介绍了STL标准库的容器,可还记得我们最开始说的STL是包括多个组件的:
容器(Containers) 迭代器(Iterators) 算法(Algorithms)
函数对象(Function Objects)适配器(Adapters)
在昨天讲容器时除了使用下标经行遍历访问修改的操作,送代器也是个很好的选择,昨天你可能不太了解他,还在问我"啊,啥是送代器啊,讲的不清楚,我要取关你"我只能说:"不是我讲的是容器,自己上网查去" "知识是关联的,像一张大网,看完今天的文章你就会了 "
今天我们就继续介绍c++STL中为容器服务的送代器,今天的文章可能不长,但还希望你认真看完
2.送代器的介绍
C++迭代器是一种用于访问容器中元素的对象,它类似于指针,可以在容器中移动并访问元素。迭代器提供了一种统一的方式来遍历容器,无论容器的类型如何,都可以使用相同的语法来访问元素。在C++标准模板库(STL)中,迭代器是一种重要的概念,它被广泛应用于各种容器类,如vector、list、set等。
迭代器的作用是将容器中的元素抽象为一个个对象,通过迭代器可以对容器中的元素进行遍历、访问和修改。迭代器提供了一系列的操作方法,如移动到下一个元素、移动到上一个元素、获取当前元素的值等。通过使用迭代器,我们可以方便地对容器中的元素进行操作,而不需要关心容器的具体实现细节。
在C++中,迭代器分为正向迭代器和反向迭代器。正向迭代器用于从容器的起始位置向结束位置遍历,而反向迭代器则相反,从容器的结束位置向起始位置遍历。通过使用迭代器,我们可以灵活地选择遍历容器的方向,以满足不同的需求。
迭代器的失效是指在对容器进行修改后,原先获取的迭代器可能不再有效。这是因为容器的结构发生了改变,原先的迭代器指向的位置可能已经被其他元素占据或者被删除。为了避免迭代器失效,我们需要注意在对容器进行修改操作时,尽量避免使用迭代器进行遍历或者修改。如果确实需要在遍历过程中对容器进行修改,可以使用插入或者删除操作后更新迭代
扩展总结为下表
名称 | 功能 |
---|---|
反向迭代器(reverse_iterator) | 又称“逆向迭代器”,其内部重新定义了递增运算符(++)和递减运算符(–),专门用来实现对容器的逆序遍历。 |
安插型迭代器(inserter或者insert_iterator) | 通常用于在容器的任何位置添加新的元素,需要注意的是,此类迭代器不能被运用到元素个数固定的容器(比如 array)上。 |
流迭代器(istream_iterator / ostream_iterator) 流缓冲区迭代器(istreambuf_iterator / ostreambuf_iterator) | 输入流迭代器用于从文件或者键盘读取数据;相反,输出流迭代器用于将数据输出到文件或者屏幕上。 输入流缓冲区迭代器用于从输入缓冲区中逐个读取数据;输出流缓冲区迭代器用于将数据逐个写入输出流缓冲区。 |
移动迭代器(move_iterator) | 此类型迭代器是 C++ 11 标准中新添加的,可以将某个范围的类对象移动到目标范围,而不需要通过拷贝去移动。 |
3.送代器
3.1反向送代器
反向送代器模板类
// iterator T& T*
template<class Iterator, class Ref, class Ptr>
3.1.1定义
// iterator T& T*
template<class Iterator, class Ref, class Ptr>
struct reverse_iterator
{
Iterator cur;
typedef reverse_iterator<Iterator, Ref, Ptr> reverse_iterator;
//val
}
可以用struct也可以用class
// iterator T& T*
template<class Iterator, class Ref, class Ptr>
class reverse_iterator
{
Iterator cur;
typedef reverse_iterator<Iterator, Ref, Ptr> reverse_iterator;
//val
}
其中cur是正向代送器
构造函数需要传入一个正向迭代器,初始化给我们的成员变量
reverse_iterator(Iterator it)
:cur(it)
{}
reverse_iterator& operator++()
{
--cur;
return *this;
}
reverse_iterator operator++(int)
{
reverse_iterator tmp(cur);
cur;
return tmp;
}
reverse_iterator& operator--()
{
++cur;
return *this;
}
reverse_iterator operator--(int)
{
reverse_iterator tmp(_cur);
++cur;
return tmp;
}
Ref operator*()
{
Iterator tmp = _cur;
--tmp;
return *tmp;
}
Ptr operator->()
{
return (&operator*());
}
bool operator!=(const reverse_iterator& r)
{
return cur != r.cur;
}
bool operator==(const reverse_iterator& r)
{
return cur == r.cur;
}
库中的反向迭代器在设计时,为了最求极致的对称,rbegin()
指向最后一个有效元素的下一个位置,rend()
指向第一个有效元素(位置是与正向迭代器相反的)
模板
template<class Iterator>
类
template<class T>
class vector
{
public:
//……
//=====反向迭代器=====
typedef __reverse_iterator<iterator, T&, T*> reverse_iterator;
typedef __reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
//……
private:
iterator _start; //指向起始位置
iterator _finish; //指向有效元素的下一个位置
iterator _end_of_storage; //指向可用空间的下一个位置
};
3.1.2反向送代器遍历
void TestVector9()
{
int arr[] = { 1,2,3,4,5,6,7,8,9 };
vector<int> v(arr, arr + sizeof(arr) / sizeof(arr[0]));
vector<int>::reverse_iterator rit = v.rbegin();
while (rit != v.rend())
{
cout << *rit << " ";
++rit; //反向迭代器++,就是--
}
cout << endl;
}
4.总结
总之,C++迭代器是一种强大的工具,它提供了一种统一的方式来访问容器中的元素。通过使用迭代器,我们可以方便地对容器进行遍历、访问和修改。然而,我们需要注意迭代器的失效问题,避免在对容器进行修改时导致迭代器失效。
(借鉴【C++】反向迭代器--迭代器适配器_c++反迭代器-优快云博客C++ STL学习之【反向迭代器】_c++ stl 反向迭代器-优快云博客)