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;//将迭代器类重名名为iterator

	Node* _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~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达2022机器学习专项课程(一) 5.4 多元线性回归的梯度下降

问题预览/关键词 多元线性回归的函数是&#xff1f;如何向量化表达&#xff1f;如何计算多元线性回归的成本函数的梯度&#xff1f;正规方程法是什么&#xff1f;正轨方程法的缺点是什么&#xff1f; 笔记 1.多元线性回归函数 5.1章节描述过。 向量化函数 原版函数 2.计…

设计模式——桥接模式07

桥接模式是将抽象部分与实现部分分离&#xff0c;可实现两部分的组合使用。 例如 遥控器 &#xff08;抽象部分&#xff09;与 设备&#xff08;实现部分 电视&#xff0c;空调等&#xff09;。遥控器调用的是 设备方实现的接口。 设计模式&#xff0c;一定要敲代码理解 抽象模…

基于springboot实现学科竞赛管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现学科竞赛管理系统演示 摘要 随着国家教育体制的改革&#xff0c;全国各地举办的竞赛活动数目也是逐年增加&#xff0c;面对如此大的数目的竞赛信息&#xff0c;传统竞赛管理方式已经无法满足需求&#xff0c;为了提高效率&#xff0c;竞赛管理系统应运而生。…

springboot国际化多语言

1,新建国际化多语言文件 在resources目录下新建 messages.properties 其他语言的文件 编辑messages.properties文件,下方从text切换到Resource Bundle ,即可对照着编辑多语言文件 (如果没有找到Resource Bundle,先在settings->plugins中安装Resource Bundle Editor) 2,配…

爬取学习强国视频小示例

因为需要爬取的视频数量并不是很大&#xff0c;总共需要将131个视频下载下来&#xff0c;所以就直接去手动找找视频的地址和名称保存下来的。由于页面是动态加载的&#xff0c;所以我们无法在网站源码中直接找到视频的超链接。设想是可以用Selenium模拟浏览器点击进行动态加载获…

重装系统之后,电脑连网卡都没反应怎么办?

前言 有些电脑比较奇葩&#xff0c;安装完成之后会出现网卡连驱动都没有&#xff0c;这时候要安装电脑驱动可是真的烦躁。怎么下手呢&#xff1f; 如果确定电脑的网卡型号还好&#xff0c;直接找个电脑下载个对应的网卡驱动&#xff0c;用U盘复制过去就能安装。 但如果不知道…

openharmony launcher 调研笔记(02)UI 调用逻辑

最近在看launcher&#xff0c;把自己调研的点做个笔记&#xff0c;持续修改更新中&#xff0c;个人笔记酌情参考。 EntryView Column() { PageDesktopLayout(); } .height(this.workSpaceHeight) // this.mWorkSpaceHeight this.mScreenHe…

【深度学习】海洋生物数据集,图片分类

文章目录 任务描述数据收集数据处理模型训练指标评测web app代码和帮助 任务描述 收集9种以上的海洋生物图片&#xff0c;然后基于深度学习做一个分类模型&#xff0c;训练完成后&#xff0c;分类模型就可以对未知图片进行分类。 在之后随便传一张图片&#xff0c;分类模型就…

016——DHT11驱动开发(基于I.MX6uLL)

目录 一、 模块介绍 1.1 简介 1.2 电路描述 1.3 通信协议 二、 驱动程序 三、 应用程序 四、 上机实验 一、 模块介绍 1.1 简介 DHT11 是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器&#xff0c;会测量空气中湿度&#xff0c;再根据测量结果决定是否继续加…

【vite】-【vite介绍】-【vite的基础应用】-【vite的高级应用】-【

目录 vite介绍vite的基础应用vite创建项目vite创建vue3项目vite创建vue2项目vite创建react项目 vite中使用css的各种功能vite中使用tsvite中处理静态资源的方法vite集成eslint和prettiervite中的env环境变量 vite的高级应用 vite介绍 一、特点&#xff1a; 开发时效率极高开箱…

springcloud第4季 springcloud-gateway网关的功能作用

一 网关 1.1 gateway的作用 网关可以实现&#xff1a; 权限过滤拦截&#xff0c;请求转发&#xff1b;组包拆包&#xff0c;加密解密&#xff0c;报文解析&#xff0c;协议转换等功能。 cloud gateway本身也是一个微服务&#xff0c;需要注册进服务到注册中心&#xff0c;从…

LeetCode 378 有序矩阵中第K小的元素

题目信息 LeetoCode地址: . - 力扣&#xff08;LeetCode&#xff09; 题解内容大量转载于&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目理解 题意很直观&#xff0c;就是求二维矩阵中所有元素排序后第k小的数。 最小堆写法 该写法不再赘述&#xff0c;维护…

simulink的硬件支持下,串口发送的模型,stm32f407的串口程序调试错误

串口调试助手能接收到数据&#xff0c;为何是8个数据&#xff1f;如之奈何&#xff1f; 参考文章&#xff1a; STM32CubeMxMATLAB Simulink串口输出实验_用stm32cubemx生成的串口都是输出-CSDN博客根据 该文章发送字符串 hello&#xff0c;发送数量为5&#xff0c;接收也是he…

解读命令:icacls “E:\ShareAll“ /grant “Everyone:(OI)(CI)(F)“

命令 icacls "E:\ShareAll" /grant "Everyone:(OI)(CI)(F)" 是在Windows操作系统中用来修改文件或目录权限的命令行操作。该命令执行以下操作&#xff1a; 路径&#xff1a;"E:\ShareAll" 指定了要更改权限的目录位置&#xff0c;即对E盘下的“S…

Cisco Packet Tracer配置AAA认证

出口路由器R1配置&#xff1a; ip domain-name cisco.com;写入设备的默认域名 crypto key generate rsa;产生rsa密钥 ip ssh secret cisco;启用ssh服务 enable secret cisco;设置特权模式密码 连接TACAS的路由器做同样配置 RADIUS服务器的配置 client ip 配置成RADIUS服务器…

二分法题集2

目录 1 山脉数组的峰顶索引 分析&#xff1a; 代码展示&#xff1a; 2 寻找峰值 分析&#xff1a; 代码展示&#xff1a; 3 寻找旋转排序数组中的最小值 分析&#xff1a; 代码展示&#xff1a; 4 点名 分析&#xff1a; 代码展示&#xff1a; 1 山脉数组的峰顶…

数据结构学习——栈和队列

1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 …

《BERT》论文笔记

原文链接&#xff1a; [1810.04805] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding (arxiv.org) 原文笔记&#xff1a; What&#xff1a; BETR&#xff1a;Pre-training of Deep Bidirectional Transformers for Language Understand…

Ruoyi-vue-pro Vue + nginx 二级目录部署到云服务器

http://www.your-server.com/ 这是一级目录&#xff0c;由于项目多&#xff0c;一般会通过二级域名http://oa.your-server.com/或二级目录http://www.your-server.com/oa来发布&#xff0c;本篇记录一下二级目录发布。先看效果 1、router/index.js配置base export default new …

对代理模式的理解

目录 一、前言二、案例1 代码2 自定义代理类【静态代理】2.1 一个接口多个实现&#xff0c;到底注入哪个依赖呢&#xff1f;2.1.1 Primary注解2.1.2 Resource注解&#xff08;指定name属性&#xff09;2.1.3 Qualifier注解 2.2 面向接口编程2.3 如果没接口咋办呢&#xff1f;2.…