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

C++——list常见函数的使用和模拟实现(2)

        在list的上一篇博客里实现了list基本的初始化、插入数据、删除数据的基本功能,这些功能的实现方式只是在原先链表的实现里加入了模版而已,但是list作为一个容器,它还有一个基础的东西——迭代器。list的迭代器和之前实现的string和vector很大不同,这里就专门进行list迭代器基本功能的模拟实现。

        list的迭代器本质上是一个指向list结点的一个指针,但是因为list的结点在内存中的分布不是连续的,所以如果直接用一个原生的指针作为迭代器的话,在后续的操作中会有非常多的不同,所以我们把指针也封装成一个类,这样进行很多操作的时候就会更加方便。也是因为上面说的,list的结点在内存中的分布不是连续的,所以list迭代器并没有+= 、-=这样的操作。

        因为我们list本身就是一个模板类,所以它的迭代器也一定要是一个模板类才能够匹配上,迭代器的成员变量很简单,就是一个指向list结点的一个指针,所以在初始化的时候把这个某个结点赋值给成员变量即可。这个成员变量的类型一定是一个list结点的指针,我们后续的操作也是根据这个指针来的,所以这里我们typedef一下list_Node<T>,list_Node<T>就是list存储的数据的类型,方便后续的操作。

    template<class T>struct list_Iterator{typedef list_Node<T> Node;Node* _node;list_Iterator(Node* node):_node(node){}}

        首先基本的就是对迭代器的解引用操作和->操作了。这个解引用操作符的重载很常规,只要返回这个内容的引用就行了,但是->操作符的重载却没有那么简单。因为本身我们的迭代器本身本质上就是一个指针,那么对这个指针用->那不是访问迭代器里的内容吗,但是->不应该要访问到内内容里的嘛,这样这个运算符重载不就改变了这个运算符的意义了吗。实际上在对迭代器使用->时,编译器是把xxx..operator->()->自动优化成了一个->,这样就能实现->原本的含义了,所以->返回的一个是一个结点数据的指针,因此才有了下面的写法。

   T& operator*(){return _node->_data;}//iterator.operator->()->...T* operator->(){return &(_node->_data);}

        ++和--操作的本质都是返回一个指向上一个或下一个结点的指针,也就是返回一个迭代器,为了方便操作,我们也可以typedef一下自身的类型。list本身就是一个双向带头循环列表,所以用迭代器指向的这个结点就能很轻松的找到前一个或后面一个结点。

    typedef list_Iterator<T> Self;Self& operator++(){_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}

        判断运算符的重载就更简单了,但是要注意的是,我们要判断的是两个结点的地址是否相同吗,不是比较结点存储的是否相同。

    bool operator!=(const Self& s) const{return _node != s._node;}bool operator==(const Self& s) const{return _node == s._node;}

        上面就完成了list迭代器的基本实现,但是如果这样写的话,我们会发现,如果要实现const迭代器的话,这样是不行的,因为如果我们只是简单的在iterator前加上一个const是不能实现我们的要求的,因为如果简单的用const修饰iterator的话,这样变成了iterator的指向不能改变,但是我们依旧可以修改iterator指向的那个结点保存的内容,和我们const_iterator的要求:指向可以改变,但是不能改变所指的内容的要求完全不符,所以不能直接这样简单的实现。

        同时我们在实现iterator的时候返回值也有所不同,这里就正好用模板就可以解决这个问题了,首先我们的const_iterator的解引用操作是->时不允许修改内容的,这里两种迭代器的不同需求我们可以通过模板解决,第一步就是在给迭代器的模板增加两个模板参数,其中Ref表示保存数据类型的引用,Ptr表示保存数据类型的指针。解引用操作符重载的返回值类型用Ref代替,->操作符重载的返回值用Ptr代替。

    template<class T,class Ref ,class Ptr>

        第二步,在list类的内部增加两个typedef,iterator就是一个正常的迭代器的类型,不过因为是上一点的原因我们要多加两个模板参数,而const_iterator的模板参数的类型则有变化,因为const_iterator的指向是可以改变的,所以要在模板参数里加上const,把const加在T之前,这样在迭代器里,使用解引用操作符和->操作符的时候就不能对保存的数据进行操作了,这样就实现了代码的复用。

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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Spring Boot实现大文件分片下载
  • 内网渗透—横向移动非约束委派约束委派
  • 深度学习每周学习总结N9:transformer复现
  • 基于OMS构建OceanBase容灾双活架构的实践
  • 深入理解Elasticsearch的`_source`字段与索引优化
  • [C#学习笔记]LINQ
  • 企业微信运营工具:赋能企业数字化转型的利器
  • Playwright 和 Selenium的对比
  • 7.认识进程
  • 积分第二中值定理的证明
  • 结构开发笔记(七):solidworks软件(六):装配摄像头、摄像头座以及螺丝,完成摄像头结构示意图
  • 智慧赋能,铸就国防工业新辉煌-程易科技助力某军工企业数字化转型纪实
  • 【区块链通用服务平台及组件】微言科技数据智能中台
  • 一个成熟的软件测试工程师应该具备那些“技能”
  • 探索Python的隐秘角落:Keylogger库的神秘面纱
  • [iOS]Core Data浅析一 -- 启用Core Data
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • avalon2.2的VM生成过程
  • Codepen 每日精选(2018-3-25)
  • extract-text-webpack-plugin用法
  • IP路由与转发
  • laravel 用artisan创建自己的模板
  • Promise面试题2实现异步串行执行
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • Shadow DOM 内部构造及如何构建独立组件
  • vue 配置sass、scss全局变量
  • 从零开始的无人驾驶 1
  • 看域名解析域名安全对SEO的影响
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端临床手札——文件上传
  • 如何学习JavaEE,项目又该如何做?
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 中文输入法与React文本输入框的问题与解决方案
  • 追踪解析 FutureTask 源码
  • 字符串匹配基础上
  • Hibernate主键生成策略及选择
  • hi-nginx-1.3.4编译安装
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (7) cmake 编译C++程序(二)
  • (C#)一个最简单的链表类
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (PySpark)RDD实验实战——取最大数出现的次数
  • (初研) Sentence-embedding fine-tune notebook
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等