• 反向迭代器


    目录

    一,反向迭代器的概念

    二,反向迭代器的实现

    1.明确我们的反向迭代器是一个模板

    2.实现 

    1.成员及其初始化

    2.各种类型的operator函数重载

    三,总结


    一,反向迭代器的概念

         按我的理解来说,反向迭代器其实就是一个封装起来的指针。它的成员就是一个指针,然后在里面实现一系列的运算符重载来实现一些功能。但是反向迭代器的实现有时候要在正向迭代器实现以后再来实现。因为反向迭代器里面包含了很多对于正向迭代器功能的复用。并且反向迭代器里面的成员要是正向迭代器的类型

    二,反向迭代器的实现

    1.明确我们的反向迭代器是一个模板

    因为我们的反向迭代器不是只给一个类型使用的,所以我们要将方向迭代器实现为一个模板类。如下:

    1. template<class iterator,class Ref,class Ptr>
    2. class reverse_iterator
    3. {
    4. };

    要实现这个模板类首先便是要确定这个模板类的模板参数有几个,这里我写的模板参数有三个。第一个表示的是迭代器的类型,第二个表示引用,第三个表示一个指针类型。第一个类型是给反向迭代器的成员使用的,因为反向迭代器的成员是正向迭代器类型。引用便是给解引用用的。指针类型便是给"->"用的。

    2.实现 

    1.成员及其初始化

    首先便是要定义成员以及初始化函数:

    1. template<class iterator,class Ref,class Ptr>
    2. class reverse_iterator
    3. {
    4. reverse_iterator(const iterator& it)
    5. :_it(it)
    6. {}
    7. private:
    8. iterator _it;//成员
    9. };

    成员是正向迭代器的成员,在拷贝构造时也要使用正向迭代器的成员初始化。

    2.各种类型的operator函数重载

    1.首先便要实现"*"解引用操作,在反向迭代器里面实现这个操作其实就是一种复用的行为。

    这里要返回的类型是Ref类型,我们怎么从一个iterator类型的对象得到一个Ref类型的对象呢?这里便要复用一下正向迭代器的"*"。如下:

    1. Ref operator*()
    2. {
    3. return *_it;//调用正向迭代器的解引用
    4. }

    2."->"操作符重载,这个操作符的实现其实也是一个复用的结果。我们只需要调用正向迭代器的"->"便可以了,并且它的返回类型是Ptr类型:

    1. Ptr operator->()
    2. {
    3. return _it.operator->();//显示调用整形迭代器的->
    4. }

    3.++运算符的实现其实就是要和正向迭代器的++反着来,正向迭代器的++是指针向前走,反向迭代器的++便是指针往后走。如下:

    1. self operator ++()
    2. {
    3. --_it;//还是复用了正向迭代器的--
    4. return *this;
    5. }

    这里要注意的是:

    我们的返回值是反向迭代器的类型,因为反向迭代器其实是一个模板,模板的类名是类名类型是类型。但是我们为什么能用类名来表示类型呢?这是因为我使用了类型重定义函数:

    1. typedef reverse_iterator self;

    有了上面的经验以后我们便可以来实现其它的操作符,其实也还是复用:

    1. typedef reverse_iterator self;
    2. self operator ++()
    3. {
    4. --_it;//还是复用了正向迭代器的--
    5. return *this;
    6. }
    7. self operator ++(int)
    8. {
    9. _it--;//还是复用了正向迭代器的后置--
    10. return *this;
    11. }
    12. self operator --()
    13. {
    14. ++_it;//还是复用了正向迭代器的++
    15. return *this;
    16. }
    17. self operator --(int)
    18. {
    19. _it++;//还是复用了正向迭代器的后置++
    20. return *this;
    21. }

    4.比较操作符,在迭代器里面我们要实现的比较操作符只有两个。这两个便是"!="和"=="。返回类型都是bool类型。代码如下:

    1. bool operator!=(const reverse_iterator& it)
    2. {
    3. return _it != it._it;
    4. }
    5. bool operator==(const reverse_iterator& it)
    6. {
    7. return _it == it._it;
    8. }

    这里要注意的是千万不要将_it != it._it写成it._it!=_it.也就是不要调换两者的位置。这是因为在右操作的左边还有一个this->解引用。this的类型是reverse_iterator类型,reverse_iterator里面的成员是_it而不是it._it。

    三,总结

    如果你曾经实现过正向迭代器的话,你会发现这个反向迭代器的实现是比正向迭代器实现的方式简单的多的。为什么呢?这是因为我们的反向迭代实现的时候使用了一种叫做适配器模式的实现方式。用这种方式来实现便可以大量复用正向迭代器里面实现的方法!!!

  • 相关阅读:
    写给开发人员的实用密码学(七)—— 非对称密钥加密算法 RSA/ECC
    你了解过<string.h>里的函数吗,今天带你模拟实现代表性函数
    龟速乘 - a * b爆ll且模数很大时的计算方法
    【效率提升】手把手教你如何使用免费的 Amazon Code Whisperer 提升开发效率堪比 GitHub Copilot 平替
    OpenCV中的像素重映射原理及实战分析
    WordPress初学者入门教程-附录一搜索引擎优化(SEO)
    coco2017数据集COCO格式转YOLO格式
    039-第三代软件开发-PDF阅读器
    java毕业生设计学校图书馆管理系统计算机源码+系统+mysql+调试部署+lw
    大型园区网络建设与管理-网络管理7.1
  • 原文地址:https://blog.csdn.net/qq_41934502/article/details/133799500