【C++】反向迭代器的设计

简介: 【C++】反向迭代器的设计

一、反向迭代器的结构

我们设计的反向迭代器是用正向迭代器实现的,这样反向迭代器的实现方式就统一了,那么我们反向迭代器的成员变量就是一个正向迭代器,关于成员函数,我们反向迭代器提供的接口与正向迭代器提供的接口一样。

//第一个模板参数传递 正向迭代器,第二个传递 迭代器的引用 第三个传递 迭代器的地址
 template<class Iterator, class Ref, class Ptr>
 //用struct定义类,因为我们想要公开我们的接口
 struct _reverse_iterator
 {
  //对自己进行typedef方便使用
  typedef _reverse_iterator<Iterator, Ref, Ptr> self;
    //成员变量 是一个正向迭代器
    Iterator _current;
    //构造函数   用一个正向迭代器进行初始化反向迭代器对象
    _reverse_iterator(Iterator it)
        :_current(it)
    {}
    //*运算符重载
    Ref operator*();
    //前置++运算符重载
    self& operator++();
    //后置++运算符重载
    self operator++(int)
    //前置--运算符重载
    self& operator--()
    //后置--运算符
    self operator--(int)
    //->操作符
    Ptr operator->()
    //关系运算符
    bool operator!=(const self& s);
    bool operator==(const self& s);
 }

容器类内的rbeginrend 函数

//类内使用反向迭代器
class myclass
{
     //此类内要配套有一个正向迭代器iterator,然后传给外面的反向迭代器
     //将反向迭代器进行typedef方便使用
     typedef _reverse_iterator<iterator, T&, T*> reverse_iterator;
      //反向迭代器
     typedef _reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;
     //反向迭代器
     reverse_iterator rbegin()
     {
      return reverse_iterator(end());
     }
     reverse_iterator rend()
     {
      return reverse_iterator(begin());
     }
     //const反向迭代器
     const_reverse_iterator rbegin() const
     {
      return const_reverse_iterator(end());
     }
     const_reverse_iterator rend() const
     {
      return const_reverse_iterator(begin());
     }
};

注意: 反向迭代器这里我们采用了对称结构便于理解对比,但这也导致我们后面在进行*解引用操作符时要解引用前一个位置!

二、反向迭代器的接口实现

1、*运算符重载

我们可以创建一个局部对象,对局部对象进行--找到前一个位置,然后再进行解引用返回就行了。

//*运算符重载
Ref operator*()
{
  //这里是不用写拷贝构造的,默认的拷贝构造会对内置类型进行值拷贝,对自定义类型调用它的拷贝构造
  Iterator tmp = _current;
  --tmp;
  return *tmp;
}

2、算术运算符 ++ - -的重载

由于我们的反向迭代器是由正向迭代器实现的,反向迭代器++就相当于正向迭代器- - ,明白了这个就很好实现算术运算符重载了。

//前置++运算符重载
self& operator++()
{
  --_current;
  return(*this);
}
//后置++运算符重载
self operator++(int)
{
  //保存当前对象
  self tmp(*this);
  --_current;
  //返回--之前的对象
  return tmp;
}
//前置--运算符重载
self& operator--()
{
  ++_current;
  return (*this);
}
//后置--运算符
self operator--(int)
{
  self tmp(*this);
  ++_current;
  return tmp;
}

3、->操作符重载

->运算符重载我们只需要返回容器中存储的自定义类型的对象的地址就行了,我们可以先调用operator*()拿到容器中存储的对象,然后再进行取地址&

Ptr operator->()
{
  return &(operator*());
}

3、关系运算符

要判断两个反向迭代器相不相等,只需要判断反向迭代器里面的成员变量相不相等就行了。

//关系运算符
bool operator!=(const self& s)
{
  return _current != s._current;
}
bool operator==(const self& s)
{
  return _current == s._current;
}

到这里我们的反向迭代器就已经形成了。

三、关于反向迭代器的一些讨论

由于我们的反向迭代器是用模板写的,当我们将vector的迭代器类型传递过去时,我们的反向迭代器就变成了vector的反向迭代器,当我们将list的迭代器传递过去时,就形成了list的反向迭代器。

传递的迭代器必须的二元迭代器,可以++ ,- -。forward_list的迭代器就不行!

例如:实现vector的反向迭代器,我们只需要在类内部传递一下正向迭代器,然后typedef一下就行了。

template<class T>
class vector
{
public:
  //正向迭代器
  typedef  T* iterator;
  //反向迭代器   将正向迭代器进行传递给反向迭代器
  typedef _reverse_iterator<iterator, T&, T*> reverse_iterator;
  typedef _reverse_iterator<iterator, const T&, const T*> const_reverse_iterator;
  //普通迭代器  ------------------------------------------------
  iterator begin();
  iterator end();
  //const迭代器
  typedef const T* const_iterator;
  const_iterator begin() const;
  const_iterator end() const;
  //反向迭代器
  reverse_iterator rbegin()
  {
    return reverse_iterator(end());
  }
  reverse_iterator rend()
  {
    return reverse_iterator(begin());
  }
  //const反向迭代器
  const_reverse_iterator rbegin() const
  {
    return const_reverse_iterator(end());
  }
  const_reverse_iterator rend() const
  {
    return const_reverse_iterator(begin());
  }
  ...... 
  ...... 
  ...... 
};
相关文章
|
监控 Java 大数据
如何在Java中实现批量数据处理
如何在Java中实现批量数据处理
|
资源调度 前端开发
|
存储 数据处理 C++
C++中的指针:深入理解与应用
C++中的指针:深入理解与应用
129 1
|
JavaScript 前端开发 算法
vue核心语法1
vue核心语法1
144 3
|
前端开发 应用服务中间件 Linux
Halo博客搭建
Halo博客搭建
654 1
|
前端开发 算法 调度
【芯片前端】与RR调度的相爱相杀——verilog实现RR调度器1
【芯片前端】与RR调度的相爱相杀——verilog实现RR调度器1
736 0
【芯片前端】与RR调度的相爱相杀——verilog实现RR调度器1
|
JavaScript
ElementUI 常用组件使用方法
ElementUI 常用组件使用方法
ElementUI 常用组件使用方法
|
缓存 移动开发 NoSQL
php结合redis实现高并发下的抢购、秒杀功能的实例
php结合redis实现高并发下的抢购、秒杀功能的实例
373 0
|
网络协议 Linux 开发工具
Linux网络服务DHCP详解(我这一生都是坚定不移的唯物主义者,唯有你,我希望有来生)(一)
Linux网络服务DHCP详解(我这一生都是坚定不移的唯物主义者,唯有你,我希望有来生)(一)
493 0
Linux网络服务DHCP详解(我这一生都是坚定不移的唯物主义者,唯有你,我希望有来生)(一)
|
机器人 API Python
Python 技术篇-20行代码实现微信机器人斗图功能实例演示!斗图啦官网API调用方法
Python 技术篇-20行代码实现微信机器人斗图功能实例演示!斗图啦官网API调用方法
629 0
Python 技术篇-20行代码实现微信机器人斗图功能实例演示!斗图啦官网API调用方法