C++的list类(一):list类的常见操作和模拟实现

目录

前言

List类的迭代器

List类的模拟实现

list.h文件

test.cpp文件


前言

  • vector的insert和erase都会导致迭代器失效
  • list的insert不会导致迭代器失效,erase会导致迭代器失效

  • insert导致失效的原因是开辟了新空间后,迭代器扔指向原空间
  • erase导致失效的原因是销毁的空间不是连续的空间,迭代器找不到下一块小空间的位置

List类的迭代器问题

类模板:C++模板初阶

内部类:C++的类和对象(七):友元、内部类

问题1:原生指针不能充当迭代器(原生指针是天然的迭代器的前提是空间连续)

原因:原生指针指向的是连续空间的情况下才可以充当迭代器

  • 数组:是一片连续的存储空间,数组的原生指针数组名,++即是下一个元素的地址
  • 链表:不是一片连续的存储空间,链表的原生指针Node*,++不是下一个结点的地址

问题2:对结点的原生指针的解引用得不到当前所在结点的数据

List类的模拟实现

难点:Node、iterator、list三个类的间接嵌套使用

  • Node、iterator、list都是一个类
  • Node类负责表示的单个结点的结构,并提供相关的方法来操作单个结点
  • list类负责管理所有结点间的关系及提供对外接口来让用户操作整个链表
  • iterator类负责实现封装原生指针和实现迭代器需要的方法

结点类模板

template <class T>
struct ListNode
{ListNode<T>* _next;//结点的后继指针ListNode<T>* _prev;//结点的前驱指针T _data;//结点中存放的数据ListNode(const T& x = T())//构造Node类类型的对象(一个结点对象):_next(nullptr)//未传入指定数据,x就会等于该匿名对象,_prev(nullptr)//传入指定数据,x会等于那个指定的数据,T()不起作用,_data(x){}
};

涉及知识点

1、在定义一个类时,如果类中的数据可以公用就选struct,需要保护一部分就用class,结点中的数据和前驱后继指针应该都能被访问到,所以可以直接选用struct

2、T()是一个T类型匿名对象,在构造结点时未传入有效数据,x就会给予T()进行初始化:

  1. 若T是内置类型(如 int、float、指针等),将x将被初始化为0、0.0或nullptr等默认值

  2. T是自定义类类型,则将调用该类的默认构造函数来创建一个匿名对象

普通迭代器类模板

构造迭代器对象

template<class T>
struct ListIterator
{typedef ListNode<T> Node;//此时迭代器类可以使用结点类typedef ListIterator<T> iterator;//将迭代器类重名名为iteratorNode* _node;ListIterator(Node* node)//用_node封装原生指针,_node会被传入的原生指针初始化:_node(node)        //_node = _head->_next{}                      //_node就相当于原生指针
}

*运算符重载

//*it
T& operator*()//传引用返回避免了拷贝,且该数据可读可修改
{return _node->_data;//返回_node指向的结点对象中存放的数据_data
}
  • _node->_data会被编译器转变为*(_node)._data

->运算符重载

//a->b
T* operator->()//返回值为T*,T*表示T类型的指针
{return &_node->_data;//获取T类类型对象的地址,将它交给一个指向T类类型的对象的“匿名”指针,该指针的类型是T*,之后利用该指针去访问该对象中的成员变量的值
}

问题:为什么要返回_data的地址而不是返回_data?

答:用->访问对象中的成员,左操作数是指向该对象的指针而不是该对象本身,右操作数是要访问对象的成员(A* ptr = &aa1,ptr->_a1,ptr存放的是该对象的地址,此后就可以用ptr访问_a1了),返回的地址不用一个有名的指针承接,直接接->,此时返回的内容就类似T*类型的匿名指针( (指向对象的匿名指针)->对象的成员 )

问题:返回值类型可不可以是T&?

答:不可以,T* + 返回的地址 = 一个T*类型的指向返回地址的匿名指针,返回的地址被存放在了一个匿名指针中,T& + 返回的地址 = 未定义行为(函数返回一个对象的地址,则该函数的返回值类型必须是 该对象的类型*)

前置和后置++、--、==、!=重载

//前置++
terator& operator++()//iterator&的意思是,在使用迭代器时,++操作是在该迭代器自身进行的
{_node = _node->_next;return *this;
}//后置++(返回++前的值)
iterator operator++(int)
{iterator tmp(*this);//拷贝构造一个新的_node = _node->_next;return tmp;
}//前置--
iterator& operator--()
{_node = _node->_prev;return *this;
}//后置--(返回--前的值)
iterator operator--(int)
{iterator tmp(*this);_node = _node->_prev;return tmp;
}//不等于
bool operator!=(const iterator& it)//(const iterator& this,const iterator& it)
{return _node != it._node;//this->_node != it.node
}//等于
bool operator==(const iterator& it)
{return _node == it._node;
}

解决代码冗余的迭代器模板

涉及知识点

1、普通迭代器是迭代器本身可以修改,迭代器指向的内容也可以修改

2、const迭代器是迭代器本身可以修改,迭代器指向的内容不可以修改

3、同一命名空间下,多个类之间可以通过typedef的方式使用其他类的内容

4、

链表类模板

涉及知识点

完整代码

list.h文件

test.cpp文件

~over~

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

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

相关文章

AWS入门实践-利用S3构建一个静态网站

使用Amazon S3托管静态网站是一个流行的选择&#xff0c;因为它简单、成本效益高&#xff0c;并且易于维护。静态网站由不含服务器端脚本的文件组成&#xff0c;如HTML、CSS和JavaScript文件。下面是使用S3托管静态网站的操作步骤&#xff1a; 如果大家没有AWS免费账号&#x…

FlutterFlame游戏实践#08 | 打砖块 -关卡设计

theme: cyanosis 本文为稀土掘金技术社区首发签约文章&#xff0c;30天内禁止转载&#xff0c;30天后未获授权禁止转载&#xff0c;侵权必究&#xff01; Flutter\&Flame 游戏开发系列前言: 该系列是 [张风捷特烈] 的 Flame 游戏开发教程。Flutter 作为 全平台 的 原生级 渲…

爬虫 新闻网站 以湖南法治报为例(含详细注释,控制台版) V2.0 升级自定义查询关键词、时间段

目标网站&#xff1a;湖南法治报 爬取目的&#xff1a;为了获取某一地区更全面的在湖南法治报已发布的宣传新闻稿&#xff0c;同时也让自己的工作更便捷 环境&#xff1a;Pycharm2021&#xff0c;Python3.10&#xff0c; 安装的包&#xff1a;requests&#xff0c;csv&#xff…

Day:004(1) | Python爬虫:高效数据抓取的编程技术(数据解析)

数据解析-正则表达式 在前面我们已经搞定了怎样获取页面的内容&#xff0c;不过还差一步&#xff0c;这么多杂乱的代码夹杂文字我们怎样 把它提取出来整理呢&#xff1f;下面就开始介绍一个十分强大的工具&#xff0c;正则表达式&#xff01; 正则表达式是对字符串操作的一种…

软考113-上午题-【计算机网络】-IPv6、无线网络、Windows命令

一、IPv6 IPv6 具有长达 128 位的地址空间&#xff0c;可以彻底解决 IPv4 地址不足的问题。由于 IPv4 地址是32 位二进制&#xff0c;所能表示的IP 地址个数为 2^32 4 294 967 29640 亿&#xff0c;因而在因特网上约有 40亿个P 地址。 由 32 位的IPv4 升级至 128 位的IPv6&am…

90天玩转Python-02-基础知识篇:初识Python与PyCharm

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…

【鸿蒙 HarmonyOS】获取设备的地理位置

一、背景 获取移动设备的地理位置&#xff0c;包含&#xff1a;经度、维度、具体地理位置等&#xff0c;地理位置信息能在许多业务场景中被应用&#xff0c;如导航、地图服务、位置服务、社交媒体等。 下面以一个Demo例子&#xff0c;来实现获取设备地理位置的功能 官方文档…

springboot之mybatisPlus多表查询及分页查询

文章目录 一、多表查询二、mybatis-plus条件查询三、分页查询 一、多表查询 可能会用到的注解 这里的场景是&#xff0c;查询每个用户及其所有的订单。就是查询你的id号的同时&#xff0c;把你所有的历史订单信息都拉出来。 表结构这样 CREATE TABLE User ( id INT PRIMARY…

音视频开发之旅(83)- 腾讯音乐开源高质量唇形同步模型--MuseTalk

目录 1.效果展示 2.原理学习 3.流程分析 4.资料 一、效果展示 -- &#xff08;推理素材来源于网络&#xff0c;如有侵权&#xff0c;联系立删&#xff01;&#xff09; 唱歌效果&#xff08;歌曲有suno生成&#xff09; 用于推理的视频素材来源于网络&#xff0c;如有侵权&…

基于R语言lavaan结构方程模型(SEM)技术应用

结构方程模型&#xff08;Sructural Equation Modeling&#xff0c;SEM&#xff09;是分析系统内变量间的相互关系的利器&#xff0c;可通过图形化方式清晰展示系统中多变量因果关系网&#xff0c;具有强大的数据分析功能和广泛的适用性&#xff0c;是近年来生态、进化、环境、…

lua学习笔记7(函数的学习)

print("*****************************函数的学习*******************************") print("*****************************无参数无返回值函数的学习*******************************") function f1()print("f1函数") end f1() f2function()--…

《价值》-张磊-高瓴资本-4(下)-三个投资哲学:“守正用奇”“弱水三千,但取一瓢”“桃李不言,下自成蹊”。

我常用三句古文来概括它们&#xff1a;“守正用奇”“弱水三千&#xff0c;但取一瓢”“桃李不言&#xff0c;下自成蹊”。 守正用奇 “守正用奇”是从老子的《道德经》中总结出来的表述。老子说“以正治国&#xff0c;以奇用兵”&#xff0c;即以清净的正道来治理国家&#xf…