反向迭代器

简介: 在官方库中,反向迭代器是使用适配器封装的,即用普通的迭代器去作为适配器,然后封装出一个反向迭代器出来。

在官方库中,反向迭代器是使用适配器封装的,即用普通的迭代器去作为适配器,然后封装出一个反向迭代器出来。

 

关于迭代器的解析,在介绍实习list以及迭代器这篇文章中有较详细讲解。此处重点是反向迭代器的原理和实现。list---迭代器的原理和实现

开始实现反向迭代器

首先是类模板,Iterator代表的是适配器,Ref和Ptr代表的是引用和取地址。

template<classIterator,classRef,classPtr>classReverse_Iterator{
public:
typedefReverse_Iterator<Iterator,Ref,Ptr>Slef;
private:
Iterator_it;//_it的类型是Iterator,是传进来的适配器的类型};

image.gif

反向迭代器的++和--,即往后走和往前走:

正向迭代器的++/--,即是反向迭代器的--/++:

因为是通过正向迭代器作为适配器的,当it进行++或--的时候,就会去调用正向迭代器中的operator++()和operator--();

Slef&operator++()
    {
--it;//会调用正向迭代器的operator--();return*this;
    }
Slef&operator--()
    {
++it;//会调用正向迭代器的operator++();return*this;
    }

image.gif

反向迭代器的解引用

根据官方库中的源代码,我们可以分析得到,反向迭代器中的rbegin和rend,与正向迭代器的end()和begin()是对称的。

()NR2]`R$]_O4SWQZ6JQRQR.png

如下图:

_5)8QJX(A_MOH1G`N0O~CDQ.png

因此,当解引用的时候,需要减一步,才能解引用。比如上图:rbegin()在头节点上,减一步,就到了节点的值为4的节点上,然后一值遍历的话,最终会在遍历完1的节点后结束。

Refoperator*()
    {
Iteratortmp=_it;
return*(--tmp);
    }

image.gif

对于operator->(),返回的是数据的地址,我们可以使用operator*()拿到数据,然后取地址即可。

Ptroperator->()
    {
return*(operator*());
    }

image.gif

反向迭代器的构造函数

只需在初始化列表上,将迭代器指向的节点或顺序表中的某个位置赋值给反向迭代器的对象即可。

Reverse_Iterator(Iteratorit)
        :_it(it)
    {}

image.gif

因为是需要指向同一块地址,所以不需要深拷贝,不需要析构函数!

最后稍微完善一下即可:

template<classIterator,classRef,classPtr>classReverse_Iterator{
public:
typedefReverse_Iterator<Iterator,Ref,Ptr>Slef;
Reverse_Iterator(Iteratorit)
        :_it(it)
    {}
Refoperator*()
    {
Iteratortmp=_it;
return*(--tmp);
    }
Ptroperator->()
    {
return*(operator*());
    }
Slef&operator++()
    {
--it;
return*this;
    }
Slef&operator--()
    {
++it;
return*this;
    }
booloperator!=(constSlef&s)
    {
return_it!=s._it;
    }
private:
Iterator_it;
};

image.gif

P{QZXUW3Q(ETZ(CGHZO[MTR.png

reverse_iteratorrbegin()
        {
returnreverse_iterator(end());
        }
reverse_iteratorrend()
        {
returnreverse_iterator(begin());
        }
const_reverse_iteratorrbegin() const        {
returnconst_reverse_iterator(end());
        }
const_reverse_iteratorrend() const        {
returnconst_reverse_iterator(begin());
        }

image.gif

//反向迭代器的rbegin()reverse_iteratorrbegin()
        {
//通过end()返回链表的哨兵位头节点,然后通过构造函数将反向迭代器的对象初始化,并且是浅拷贝,指向同一块空间returnreverse_iterator(end());
        }
//反向迭代器的rend()reverse_iteratorrend()
        {
//通过begin()返回链表的尾节点,然后通过构造函数将反向迭代器的对象初始化,并且是浅拷贝,指向同一块空间returnreverse_iterator(begin());
        }
//const版本反向迭代器的rbegin()const_reverse_iteratorrbegin() const        {
returnconst_reverse_iterator(end());
        }
//const版本反向迭代器的rend()const_reverse_iteratorrend() const        {
returnconst_reverse_iterator(begin());
        }

image.gif

这样实现的反向迭代器,就可以用到list,vector等等的容器,因为只需提供适合的迭代器作为适配器即可。

相关文章
【C++】反向迭代器的实现
【C++】反向迭代器的实现
|
6月前
|
设计模式 编译器 C++
【C++】开始了解反向迭代器
这样我们就实现反向迭代器,大家可以在实际中继续体会。
47 3
|
5月前
|
编译器 容器
反向迭代器的实现
反向迭代器的实现
24 1
|
5月前
|
算法 数据处理 C++
C++一分钟之-迭代器与算法
【6月更文挑战第21天】C++ STL的迭代器统一了容器元素访问,分为多种类型,如输入、输出、前向、双向和随机访问。迭代器使用时需留意失效和类型匹配。STL算法如查找、排序、复制要求特定类型的迭代器,注意容器兼容性和返回值处理。适配器和算法组合增强灵活性,但过度使用可能降低代码可读性。掌握迭代器和算法能提升编程效率和代码质量。
53 3
|
5月前
|
编译器 C++
C++ 反向迭代器的设计与实现
C++ 反向迭代器的设计与实现
|
6月前
|
存储 编译器 C++
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
【C++/STL】list(常见接口、模拟实现、反向迭代器、)
47 0
|
6月前
|
算法 数据处理 C语言
【C++迭代器深度解析】C++迭代器类型之间的继承关系与反向迭代器的独特性
【C++迭代器深度解析】C++迭代器类型之间的继承关系与反向迭代器的独特性
99 0
|
6月前
|
C++ 容器
C++反向迭代器
C++反向迭代器
|
编译器 C++ 容器
【STL】模拟实现反向迭代器
【STL】模拟实现反向迭代器
35 1