list模拟实现

一、结点的定义

有三个成员,2个指向前面和后面的指针,一个表示结点存储T类型的值。

对于_prev和_next,类型是  list_node<T>*,不是list_node*,加上类型参数T之后,才是模板类的类型。

构造函数中,先把指针置空,然后val可以给一个默认构造的缺省值。

二、普通正向迭代器

先将list_node<T> typedef为Node,便于后续使用更方便。

一个成员变量为  Node* _node,表示迭代器当前指向的那个结点。

构造函数中,用传入的node,初始化_node,指针为内置类型,浅拷贝即可。

1、operator*()

对迭代器解引用,返回的是那个T类型的值val的引用。(无论T是内置类型还是自定义类型)

2、operator->()

返回的是val的地址。

val是结构体/自定义类型,val内部可能还有多个要访问的值

可以直接通过返回的地址/指针,用->找到其中要访问的值。

3、++/--/==

 ++是让迭代器指向下一个结点,即让其成员_node变为_node->next。--同理。

前置++和--返回下一个/前一个迭代器位置,即改变后的*this的引用

后置++和--要先用tmp保存改变前的位置,最后传值返回tmp的拷贝

三、const迭代器

首先,对于所有迭代器,都是可以++,--修改的。

对于T*这种由原生指针(指针解引用就可以访问,且内存连续,++直接找到下一个结点)构成的迭代器,直接在 T*前加const,使得其无法解引用修改存储的值即可构成const_iterator。

但由于list中,内存不连续,且有时解引用得到的val为结构体(不方便)。

我们需要对++,--,*,->等进行运算符重载,因此就要定义一个__list_iterator的结构。

直接在迭代器类型前加const是错误的,这样使得const_iterator的类型变成了一个const对象,不能进行++,--等操作。const_iterator的const修饰的是对访问那个结点的值是否具有修改的权限

如上图,返回的引用的值是否加const 修饰。

对于函数重载,我们只能通过参数类型/个数/顺序来区分,这里是仅通过返回值无法区分两个operator*()。

一种解决方法是重新定义一个const_iterator结构,仅在operator*()这里与iterator不同,但代码冗余度太大,重复部分太多。

还有一种方法是引入新的模板参数  Ref作为引用的返回值

iterator和const_iterator靠Ref和Ptr两个模板参数区分。看传入的T&和T*是否加const修饰。

实际上,两种迭代器仍然是两种结构,只不过我们用模板传入模板参数,让编译器生成了两个模板类,两个模板类通过对访问数据是否有修改来区分。

先在ls内插入数据,然后用const引用接收,在Print函数内,*cit无法被修改 

四、insert/erase

 

五、拷贝构造/operator= 

 空初始化为创建头节点,用的地方比较多,可以单独拿出来。

拷贝构造直接循环尾插即可。

赋值重载使用现代写法,交换得到_head指向拷贝得到的list。

注意:由于ls被const修饰,beign()返回的是const_iterator,需要用const迭代器接收

ls要完成交换,不能加const    std::swap需要两个参数

六、clear/析构

循环删除时迭代器会失效,接收返回值更新一下。 

 

size()函数每次统计结点个数为O(N)

也可以增加一个成员变量,每次插入时++,删除时-- 

目录

一、结点的定义

二、普通正向迭代器

1、operator*()

2、operator->()

3、++/--/==

三、const迭代器

四、insert/erase

五、拷贝构造/operator= 

六、clear/析构


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

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

相关文章

【MySQL】MySQL8.1.0版本正式发布带来哪些新特性?

文章目录 前言一、畅谈新版本二、8.1.0版本部署2.1、环境准备2.2、配置yum安装依赖2.3、用户及目录创建2.4、创建用户及组2.5、解压缩包2.6、环境变量配置2.7、创建参数文件2.8、数据库初始化2.9、启动Mysql2.10、登陆MySQL 8.1 三、新特性3.1、密码参数3.2、错误日志加强3.3、…

Spring Security OAuth2.0(6):自定义认证自定义登录页

文章目录 自定义登录界面配置自定义登录页面 自定义登录界面 \qquad 你可能想知道登录页面从哪里来&#xff1f;因为我们并没有提供任何的HTML或JSP文件。Spring Security 的默认配置没有明确设定一个登录页面的URL&#xff0c;因此Spring Security 会根据启用的功能自动生成一…

Go语言ErrGroup

Go语言ErrGroup 在并发编程里&#xff0c;sync.WaitGroup 并发原语的使用频率非常高&#xff0c;它经常用于协同等待的场景&#xff1a;goroutine A 在检查 点等待一组执行任务的 worker goroutine 全部完成&#xff0c;如果在执行任务的这些 goroutine 还没全部完成&#xf…

Godot实用代码-存取存档的程序设计

1. Settings.gd 全局变量 用于保存玩家设置 对应Settings.json 2. Data.gd 全局变量 用于保存玩具数据 对应Data.json 实践逻辑指南 1.在游戏开始的时候&#xff08;游戏场景入口的_ready()处&#xff0c; Settings.gd

day09面试题

面试题 说说对 React 的理解?有哪些特性?说说 Real DOM 和 Virtual DOM 的区别?优缺点?说说 React 生命周期有哪些不同阶段?每个阶段对应的方法是?说说 React 中的 setState 执行机制&#xff1f;说说对 React 中类组件和函数组件的理解?有什么区别? 说说对 React 的理…

Linux内核结构与特性简介

系统调用接口&#xff1a;位于最上层&#xff0c;实现了一些基本的功能&#xff0c;如read和write等系统调用。这是用户空间程序与内核交互的接口&#xff0c;提供了对内核功能的访问。 内核代码&#xff1a;位于系统调用接口之下&#xff0c;可以看作是独立于体系结构的通用内…

RabbitMQ的基本使用

RabbitMQ的基本使用 引入程序集&#xff1a;RabbitMQ.Client 生产者 /// <summary> /// ProducerWrites 写入消息 ConsumerConsumption 消费消息 /// </summary> public class ProducerWrites {public static void Send(){string path AppDomain.CurrentDomain.…

qt和vue交互

1、首先在vue项目中引入qwebchannel /******************************************************************************** Copyright (C) 2016 The Qt Company Ltd.** Copyright (C) 2016 Klarlvdalens Datakonsult AB, a KDAB Group company, infokdab.com, author Milian …

CLIP概述

文章目录 Learning Transferable Visual Models From Natural Language Supervision(使用自然语言的监督信号训练一个可迁移的视觉模型)AbstractIntroduction and Motivating WorkApproachNatural Language SupervisionCreating a Suffciently Large DatasetSelecting an Eff…

13_Linux无设备树Platform设备驱动

目录 Linux驱动的分离与分层 驱动的分隔与分离 驱动的分层 platform平台驱动模型简介 platform总线 platform驱动 platform设备 platform设备程序编写 platform驱动程序编写 测试APP编写 运行测试 Linux驱动的分离与分层 像I2C、SPI、LCD 等这些复杂外设的驱动就不…

Fortinet Accelerate 2023·中国区巡展收官丨让安全成就未来

7月18日&#xff0c;2023 Fortinet Accelerate Summit在上海成功举办&#xff01;这亦象征着“Fortinet Accelerate2023中国区巡展”圆满收官。Fortinet携手来自多个典型行业的百余位代表客户&#xff0c;以及Telstra - PBS 太平洋电信、Tenable等多家生态合作伙伴&#xff0c;…

利用数据分析告警机制,实现鸿鹄与飞书双向集成

需求描述 实现鸿鹄与飞书的双向集成&#xff0c;依赖鸿鹄的告警机制&#xff0c;可以发送用户关心的信息到飞书。同时依赖飞书强大的卡片消息功能&#xff0c;在飞书消息里面能够通过链接&#xff08;如下图&#xff09;返回到鸿鹄以方便用户进一步排查和分析问题。 解决方案 1…

【PHP面试题75】PHP有哪些魔术变量,如何使用他们?

文章目录 一、前言二、魔术变量2.1 __LINE__2.2 __FILE__2.3 __DIR__2.4 __FUNCTION__2.5 __CLASS__2.6 __TRAIT__2.7 __METHOD__2.8 __NAMESPACE__ 三、总结 一、前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP面试专区。 计划将全覆盖PHP开发领域所有的面试题&#xff0c;…

CGT Asia嘉年华|2023第四届亚洲细胞与基因治疗 创新峰会(广州站)10月升级启航

近年来&#xff0c;全球CGT发展突飞猛进&#xff0c;为遗传罕见病、难治性慢性病和肿瘤患者带来了新的希望&#xff0c;也成为整个国际领域科技竞争的未来焦点。国家发改委发布的《“十四五”生物经济发展规划》明确指出要重点发展基因诊疗、干细胞治疗、免疫细胞治疗等新技术&…

利用鸿鹄优化共享储能的SCADA 系统功能,赋能用户数据自助分析

摘要 本文主要介绍了共享储能的 SCADA 系统大数据架构&#xff0c;以及如何利用鸿鹄来更好的优化 SCADA 系统功能&#xff0c;如何为用户进行数据自助分析赋能。 1、共享储能介绍 说到共享储能&#xff0c;可能不少朋友比较陌生&#xff0c;下面我们简单介绍一下共享储能的价值…

IntelliJ IDEA - Error:Module ‘name‘ production: java.lang.NullPointerException

问题描述 Error:Module name production: java.lang.NullPointerException 原因分析 一般出现这种情况多见于 IDEA 自身的问题&#xff0c;比如&#xff1a;切换分支或者拉取最新代码时结构相差过大&#xff0c;所以解决 IDEA 自身缓存的问题即可 解决方案 Build > Rebuil…

Python高光谱遥感数据处理与高光谱遥感机器学习方法深度应用

目录 ​第一章 高光谱基础 第二章 高光谱开发基础&#xff08;Python&#xff09; 第三章 高光谱机器学习技术&#xff08;python&#xff09; 第四章 典型案例操作实践 更多推荐 本教程提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 涵盖高光谱遥感的基础…

2023年7月18日,File类,IO流,线程

File类 1. 概述 File&#xff0c;是文件和目录路径的抽象表示 File只关注文件本身的信息&#xff0c;而不能操作文件里的内容 。如果需要读取或写入文件内容&#xff0c;必须使用IO流来完成。 在Java中&#xff0c;java.io.File 类用于表示文件或目录的抽象路径名。它提供了一…

Rancher 管理 Kubernetes 集群

//Rancher 简介 Rancher 是一个开源的企业级多集群 Kubernetes 管理平台&#xff0c;实现了 Kubernetes 集群在混合云本地数据中心的集中部署与管理&#xff0c; 以确保集群的安全性&#xff0c;加速企业数字化转型。超过 40000 家企业每天使用 Rancher 快速创新。 官网&#…

selenium.chrome怎么写扩展拦截或转发请求?

Selenium WebDriver 是一组开源 API&#xff0c;用于自动测试 Web 应用程序&#xff0c;利用它可以通过代码来控制chrome浏览器&#xff01; 有时候我们需要mock接口的返回&#xff0c;或者拦截和转发请求&#xff0c;今天就来实现这个功能。 代码已开源&#xff1a; https:/…