【C++STL】list的反向迭代器

list的反向迭代器

文章目录

        • list的反向迭代器
        • reverse.h
        • 疑问1:为什么在迭代器当中不需要写深拷贝、析构函数
        • 疑问2:为什么在迭代器当中需要三个模板参数?
        • 疑问3:反向迭代器是怎么实现的?
        • 疑问4:为什么*解引用不直接返回当前值
        • 为什么要加一些不认识的typedef

v2-87a8ee6be3ce86f87e9dcfc3a00df6da_r

reverse.h

#pragma oncenamespace mudan
{template<class Iterator, class Ref, class Ptr>struct __reverse_iterator{Iterator _cur;typedef __reverse_iterator<Iterator, Ref, Ptr> RIterator;__reverse_iterator(Iterator it):_cur(it){}RIterator operator++(){--_cur;return *this;}RIterator operator--(){++_cur;return *this;}Ref operator*(){//return *_cur;auto tmp = _cur;--tmp;return *tmp;}Ptr operator->(){//return _cur.operator->();return &(operator*());}bool operator!=(const RIterator& it){return _cur != it._cur;}};
}

list.h

#include<assert.h>
#include<iostream>
#include<algorithm>
#include"reverse.h"   
using namespace std;namespace mudan
{template<class T>struct list_node{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& x = T()):_data(x), _next(nullptr), _prev(nullptr){}};// typedef __list_iterator<T, T&, T*>             iterator;// typedef __list_iterator<T, const T&, const T*> const_iterator;// 像指针一样的对象template<class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> iterator;typedef bidirectional_iterator_tag iterator_category;typedef T value_type;typedef Ptr pointer;typedef Ref reference;typedef ptrdiff_t difference_type;Node* _node;__list_iterator(Node* node):_node(node){}bool operator!=(const iterator& it) const{return _node != it._node;}bool operator==(const iterator& it) const{return _node == it._node;}// *it  it.operator*()// const T& operator*()// T& operator*()Ref operator*(){return _node->_data;}//T* operator->() Ptr operator->(){return &(operator*());}// ++ititerator& operator++(){_node = _node->_next;return *this;}// it++iterator operator++(int){iterator tmp(*this);_node = _node->_next;return tmp;}// --ititerator& operator--(){_node = _node->_prev;return *this;}// it--iterator operator--(int){iterator tmp(*this);_node = _node->_prev;return tmp;}};template<class T>class list{typedef list_node<T> Node;public:typedef __list_iterator<T, T&, T*> iterator;typedef __list_iterator<T, const T&, const T*> const_iterator;typedef __reverse_iterator<iterator, T&, T*> reverse_iterator;typedef __reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;const_iterator begin() const{return const_iterator(_head->_next);}const_iterator end() const{return const_iterator(_head);}iterator begin(){return iterator(_head->_next);}iterator end(){return iterator(_head);}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}void empty_init(){// 创建并初始化哨兵位头结点_head = new Node;_head->_next = _head;_head->_prev = _head;}template <class InputIterator>list(InputIterator first, InputIterator last){empty_init();while (first != last){push_back(*first);++first;}}list(){empty_init();}void swap(list<T>& x)//void swap(list& x){std::swap(_head, x._head);}// lt2(lt1)list(const list<T>& lt){empty_init();list<T> tmp(lt.begin(), lt.end());swap(tmp);}// lt1 = lt3list<T>& operator=(list<T> lt){swap(lt);return *this;}~list(){clear();delete _head;_head = nullptr;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}void push_back(const T& x){//Node* tail = _head->_prev;//Node* newnode = new Node(x);_head          tail  newnode//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;insert(end(), x);}void push_front(const T& x){insert(begin(), x);}iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);// prev newnode curprev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;return iterator(newnode);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return iterator(next);}private:Node* _head;};void test(){list<int> ls;ls.push_back(1);ls.push_back(2);ls.push_back(3);ls.push_back(4);ls.push_back(5);ls.push_back(6);for (auto& e : ls){cout << e << " ";}cout << endl;list<int>copy = ls;for (auto e : copy){cout << e << " ";}}
}

test.cpp

#include"list.h"
#include<list>int main(void)
{mudan::test();//list<int>ls;//ls.push_back(1);//ls.push_back(2);//ls.push_back(3);//ls.push_back(4);//ls.push_back(5);//ls.push_back(6);//for (auto e : ls)//{//	cout << e << " ";//}//cout << endl;//list<int>lt(ls);//for (auto e : lt)//{//	cout << e << " ";//}return 0;
}

疑问1:为什么在迭代器当中不需要写深拷贝、析构函数

1、因为迭代器就是希望做到浅拷贝,就是需要拿到地址而不是值,因为迭代器的修改是会影响对象中的内容的

2、因为迭代器并没有申请额外的空间,所以不需要析构,如果写了析构函数,那么调用一次迭代器那岂不是把对象都给销毁了😂😂😂

疑问2:为什么在迭代器当中需要三个模板参数?

其实这三个参数是被抽象出来的,__list_iterator<T, Ref, Ptr>等价于__list_iterator<T, T&, T>,其实在迭代器当中只有一个参数也可以正常推导,但是在list类当中只有一个参数就不行了,因为如果传递过来的是const修饰的类,然后用T&来接收的话会导致权限被缩小了,所以,为了解决这个const的问题,直接显示的定义模板参数*

typedef __list_iterator<T, T&, T> iterator;
typedef __list_iterator<T, const T&,const T
> const_iterator;**

Ref就是reference

Ptr就是pointer

疑问3:反向迭代器是怎么实现的?

反向迭代器其实就是利用正向迭代器实现的,重载一下++、–等操作符,不过逻辑上功能要反过来写

疑问4:为什么*解引用不直接返回当前值

因为begin()和end()的位置和正常实现的不一样

为什么要加一些不认识的typedef

		typedef bidirectional_iterator_tag iterator_category;typedef T value_type;typedef Ptr pointer;typedef Ref reference;typedef ptrdiff_t difference_type;

我也不知道,不加过不了编译,我太菜了😭😭😭😭😭😭

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/18979.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创建UI组件库后上传NPM

上篇已经讲了如何创建自己的组件库&#xff0c;这篇讲怎么上传npm后&#xff0c;可以下载使用 1.首先看下组件的文件结构 在index.js中要写上每个组件可以按需引用的条件 import Button from "./src/button";Button.install function(Vue) {Vue.component(Button.…

Kubernetes 容器类型 Init - pause - sidecar - app容器

目录 Kubernetes 的容器类型 Init 初始化容器 参考文档&#xff1a;Init 容器 | Kubernetes 使用 Init 容器的情况 案例&#xff1a;定义了一个具有 2 个 Init 容器的简单 Pod 你通过运行下面的命令启动 Pod&#xff1a; 发现两个Init容器都没有运行成功 查看更多详细…

Mycat【什么是Mycat、Mycat与其他中间件区别、Mycat应用场景、核心概念详解、Mycat原理】(一)-全面详解(学习总结---从入门到深化)

目录 Mycat概述_什么是Mycat Mycat概述_Mycat与其他中间件区别 Mycat概述_Mycat应用场景 Mycat概念_核心概念详解 Mycat概述_Mycat原理 Mycat部署安装_MySQL主从复制概述 Mycat概述_什么是Mycat 什么是Mycat Mycat是数据库中间件&#xff0c;所谓中间件数据库中间件是连…

Oracle语句优化 (汇总)

大部分写sql语句都是为了实现而实现&#xff0c;如果最后在投入使用的过程中没有很难接受的性能&#xff0c;基本不怎么去考虑其性能。最近刚好有点时间&#xff0c;对优化方面进修进修&#xff0c;以备不时之需。 选择最有效率的表名顺序 Oracle的解析器按照从右到左的顺序处…

欧姆龙以太网口怎么和电脑连接

捷米特JM-ETH-CP以太网通讯处理器用于欧姆龙 CP1L/ CP1E/ CP1H 系列 PLC 的以太网数据采集&#xff0c;捷米特JM-ETH-CP以太网模块不占用 PLC 通讯口&#xff0c;即编程软件/上位机软件通过以太网对 PLC 数据监控的同时&#xff0c;触摸屏可以通过复用接口与 PLC 进行通讯。支持…

MyBatis查询数据库(1)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 经过前⾯的学习咱们 Spring 系列的基本操作已经实现的差不多了&#xff0…

光伏5G多合一融合终端|光伏多合一融合终端|光伏多合一群调群控网关|分布式光伏群控群调|光伏AGC/AVC系统这几者之间什么技术关系,多少钱一套预算?

光伏5G多合一融合终端|光伏多合一融合终端|光伏多合一群调群控网关|分布式光伏群控群调|光伏AGC/AVC系统这几者之间什么技术关系&#xff0c;多少钱一套预算&#xff1f; 一&#xff1a;光伏5G多合一融合终端的功能 光伏5G多合一融合终端的功能&#xff1a;群调群控/AGC/AVC功…

【数据结构与算法】栈算法题

TS 实现栈 interface IStack<T> {push(e: T): void;pop(): T | undefined;peek(): T;isEmpyt(): boolean;size(): number; }// implements: 实现接口, 一个类可以实现多个接口 class ArrayStack<T> implements IStack<T> {private data: T[] []; // private…

Spring详解(学习总结)

目录 一、Spring概述 &#xff08;一&#xff09;、Spring是什么&#xff1f; &#xff08;二&#xff09;、Spring框架发展历程 &#xff08;三&#xff09;、Spring框架的优势 &#xff08;四&#xff09;、Spring的体系结构 二、程序耦合与解耦合 &#xff08;一&…

在Windows server 2012上使用virtualBox运行CentOS7虚拟机,被强制暂停

文章目录 问题场景排查过程处理解决事后反思 问题场景 我们的平台服务使用docker部署&#xff0c;使用docker-compose进行管理&#xff0c;部署到CentOS7的服务器里平台部署到客户环境时&#xff0c;一小部分客户&#xff0c;使用自己机房或单独的服务器。很多客户不愿意采购新…

【嵌入式Linux项目】基于Linux的全志H616开发板智能垃圾桶项目

目录 一、功能需求 二、涵盖的知识点 1、wiringPi库下的相关硬件操作函数调用 2、线程&#xff08;未使用互斥锁和条件&#xff09; 3、父子进程 4、网络编程&#xff08;socket套接字&#xff09; 5、进程间通信&#xff08;共享内存和信号量&#xff09; 三、开发环境…

Elasticsearch原理剖析

一、 Elasticsearch结构 Elasticsearch集群方案由EsMaster、EsClient和EsNode1、EsNode2、EsNode3、EsNode4、EsNode5、EsNode6、EsNode7、EsNode8、EsNode9进程组成&#xff0c;如下图所示&#xff0c;模块说明如表下所示。 说明如表&#xff1a; 名称说明ClientClient使用H…