当前位置: 首页 > news >正文

C++STL反向迭代器设计

目录

  • 反向迭代器
    • 反向迭代器的定义
    • 如何获取反向迭代器
    • 反向迭代器的操作
    • 反向迭代器与普通迭代器的关系
      • 适配器模式
      • 封装代码

反向迭代器

反向迭代器的定义

反向迭代器是一种迭代器适配器,它重新定义了递增和递减操作,使其行为在逻辑上与原始迭代器相反。
当我们对反向迭代器进行递增时,它实际上会向容器起始方向移动(即递减内部的基础迭代器);而递减则向容器末尾方向移动(递增内部的基础迭代器)。

在这里插入图片描述

如何获取反向迭代器

C++容器(如vector, list, deque等)提供了rbegin()和rend()成员函数,用于获取反向迭代器。

  • rbegin(): 返回一个指向容器最后一个元素的反向迭代器。
  • rend(): 返回一个指向容器第一个元素前一个位置的反向迭代器。

同样,还有crbegin()和crend(),它们返回常量反向迭代器。

反向迭代器的操作

反向迭代器支持与普通迭代器相似的操作,如解引用、递增、递减等。但是要注意:

解引用反向迭代器时,返回的是其内部基础迭代器前一个位置的元素的引用。这是因为反向迭代器的设计是为了提供与正向迭代器对称的行为。
具体来说,rbegin()指向最后一个元素,而rend()指向第一个元素之前,这样当使用反向迭代器遍历时,从rbegin()到rend()就相当于从最后一个元素到第一个元素。

反向迭代器与普通迭代器的关系

适配器模式

反向迭代器内部包装了一个普通迭代器(基础迭代器),并通过调整递增和递减的含义来实现反向遍历。使用了适配是的设计模式,让设计更加容易,复用率高。

注意事项:

我们在封装代码的时候,rend应返回begin(),rbegin()应返回rend()。那么在使用反向迭代器遍历的时候,解引用操作在rbegin()的时候就会解引用到end(),这样就会产生非法操作,因此我们可以在解引用的时候解引用end()–的位置,这样就可以完美避开缺陷,同时又使得迭代器与反向迭代器呈现对称关系。

在这里插入图片描述

封装代码

#pragma once
#include<iostream>namespace ReIterator{template <class Iterator , class Ref, class Ptr>class reverse_iterator{typedef reverse_iterator<Iterator, Ref, Ptr> Self;Iterator _reit;public:reverse_iterator(const Iterator& it = Iterator()):_reit(it){ }Self& operator++(){return --_reit;}Self operator++(int){return _reit--;}Self& operator--(){return ++_reit;}Self operator--(int){return _reit++;}Ref operator*() {Iterator tmp = _reit;return *(--tmp);}Ptr operator->() {Iterator tmp = _reit;tmp--;return tmp.operator->();}bool operator==(const Self& it) const{return _reit == it._reit;}bool operator!=(const Self& it) const{return _reit != it._reit;}};
}namespace mylist
{template <class T>struct ListNode{T _val = 0;ListNode *_next = nullptr;ListNode *_prev = nullptr;ListNode(const T &val = T()) : _val(val){}};template <class T>class list;template <class T, class Ref, class Ptr>class ListIterator{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> self;Node *_node;friend class list<T>;public:ListIterator(Node *node = nullptr) : _node(node){}Ref operator*(){return _node->_val;}Ptr operator->(){return &(_node->_val);}self &operator++(){_node = _node->_next;return *this;}self operator++(int){self &tmp = *this;_node = _node->_next;return tmp;}self operator--(){_node = _node->_prev;return *this;}self &operator--(int){self &tmp = *this;_node = _node->_prev;return tmp;}bool operator==(const self &it) const{return it._node == _node;}bool operator!=(const self &it) const{return it._node != _node;}};template <class T>class list{typedef ListNode<T> Node;Node *_head = nullptr;size_t _size = 0;public:typedef ListIterator<T, T &, T *> iterator;typedef ListIterator<T, const T &, const T *> const_iterator;typedef ReIterator::reverse_iterator < iterator, T&, T*> reverse_iterator;typedef ReIterator::reverse_iterator < const_iterator, const T&, const T*> const_reverse_iterator;list(){Init();}list(size_t n, const T &val = T()){Init();while (n--){push_back(val);}}list(iterator first, iterator last){Init();while (first != last){push_back(*first);first++;}}list(const list<T> &lt){Init();const_iterator it = lt.cbegin();while (it != lt.cend()){push_back(*it);it++;}}void Init(){_head = new Node;_head->_next = _head;_head->_prev = _head;}iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator cbegin() const{return _head->_next;}const_iterator cend() const{return _head;}reverse_iterator rbegin(){return end();}reverse_iterator rend(){return begin();}const_reverse_iterator crbegin() const{return cend();}const_reverse_iterator crend() const{return cbegin();}const_reverse_iterator rbegin() const{return cend();}const_reverse_iterator rend() const{return cbegin();}iterator insert(iterator pos, const T &val){Node *newnode = new Node(val);Node *next = pos._node;Node *prev = next->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = next;next->_prev = newnode;_size++;return newnode;}iterator erase(iterator pos){assert(!empty());Node *next = pos._node->_next;Node *prev = pos._node->_prev;prev->_next = next;next->_prev = prev;delete pos._node;_size--;return next;}void push_back(const T &val){// Node *newnode = new Node(val);// if (newnode != nullptr)// {//     _head->_prev->_next = newnode;//     newnode->_prev = _head->_prev;//     _head->_prev = newnode;//     newnode->_next = _head;// }insert(end(), val);}void push_front(const T &val){insert(begin(), val);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}bool empty(){return _size == 0;}size_t size(){return _size;}void print(){for (auto &e : *this){std::cout << e << " ";}std::cout << std::endl;}};}

上述代码以list为例即封装了普通的迭代器,还使用普通的迭代器适配出了反向迭代器。

http://www.dtcms.com/a/446296.html

相关文章:

  • 一文学会《C++》进阶系列之C++11
  • 腊肉网站的建设前景网页版微信可以发朋友圈吗
  • 大连凯杰建设有限公司网站wordpress 文章链接失效
  • 百度网站优化升上去国外网站入口
  • BIT*算法
  • Python常用三方模块——psutil
  • 网站开发的优势建设京东物流网站的目标是什么
  • 制作网站详细步骤爱客crm系统登录
  • Linux事件循环——高效处理多任务(高并发)
  • 【Linux】POSIX信号量、环形队列、基于环形队列实现生产者消费者模型
  • SELinux系列专题(一):SELinux是什么?
  • 三角函数公式全归纳
  • 热 动漫-网站正在建设中-手机版wordpress活动报名
  • 建设银行扬中网站织梦网站仿站
  • 网站建设公司伟置鄂尔多斯 网站制作
  • Hi3516DV500/HI3519DV500开发笔记之例程编译和测试
  • 路由策略与路由控制实验
  • Leetcode 84. 柱状图中最大的矩形 单调栈
  • 专门用来制作网页的软件是河南网站关键词优化
  • 什么是企业网站策划案企业网站空间买虚拟主机
  • 高并发场景下API网关的熔断策略:Hystrix与Sentinel的对比测试
  • llama.cpp Flash Attention 论文与实现深度对比分析
  • Python 3 与 MongoDB 的集成指南
  • 网站生成手机端wordpress高亮插件
  • 基础动态规划问题
  • js多久可以做网站网站建设后帐号密码
  • 第十五篇:Python高效调试与性能优化技巧
  • leetcode 66.加一 python
  • 书生浦语实战营L1-G4000探索大模型能力边界
  • Prometheus 05-02: 告警规则与Alertmanager配置