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

C++ list模拟实现

文章里用到查询C++的网址为:cplusplus.com - The C++ Resources Network

源代码是stl30.tar.gz


目录

前言

一、成员变量

二、构造函数

三、push_back()

四、迭代器

(1)普通迭代器

(2)const迭代器

(3)迭代器失效

五、insert

六、erase,pop_back,pop_front

七、operator->

八、析构函数,拷贝构造函数,赋值重载,clear,swap


前言

我们list的实现依旧先从源代码入手,我们需要搞清楚部分的逻辑,这样方便我们去模拟实现。

link_type是节点的指针。接着我们去观察一下无参的初始化。

这里弄得是哨兵位的节点。get_node是在内存池申请内存,类似malloc申请空间不初始化。

接着我们来浅浅的观察一下push_back。某个位置前面插入。

所以其实我们明白链表的结构,很多都能够大概猜测出来。

一、成员变量

首先链表我们需要定义一个节点,只是我们这里需要用模板来实现。

还需要完成构造函数。

接着就完成成员变量的创建。(typedef只是为了写代码简单一点)

二、构造函数

我们先完成无参的构造函数,源代码中是用内存池,但我们这里简单实现一下,new也是动态开辟的空间。

这里我们再实现简单的size()和empty()。

三、push_back()

push_back逻辑上也很简单,因为是双向循环链表,我们需要先创建一个新节点,然后把新节点的尾指针指向哨兵位,旧的尾节点的下一个指针指向新的节点,新节点的头指针也要指向旧节点,哨兵位的头指针指向新节点。

四、迭代器

(1)普通迭代器

迭代器我们就不能单纯使用原生指针来,因为list两个节点之间物理上没有联系,我们加加也不会到下一个节点去。所以我们先观察一下源代码里面是怎么实现的。

重载了解引用返回节点数据。

也重载了++。

我们链表做不到vector和string结构的连续,但是我们list有着下一个节点的地址,所以我们可以用类型对节点指针进行封装来实现。我们就可以定义struct迭代器,struct默认公有,class则默认是私有。

这样我们完成了对自己list迭代器的封装,我们就可以去实现迭代器的begin()等等。

(2)const迭代器

我们要分清楚const iterator是迭代器本身不能修改,而我们要模拟实现的是const_iterator是指向内容不能修改。

但我们这样复制过来一个类,有点复杂了,我们先来看看库里面是怎么实现的呢?

但在编译后其实本质是相同的,一个是我们自己实现的,一个是通过类模板让编译器实例化出两个不同的类。

(3)迭代器失效

我们能够发现在list中,我们跟之前vector相似的代码,却不会发生迭代器失效。因为vector会挪动数据,而list位置不是连续的,在这种情况不会失效。

那在什么情况会发生迭代器失效呢?在删除一个节点,如果不重置的话,就相当于访问野指针了。

五、insert

insert是在pos位置插入数据。所以要拿到当前位置和前一个位置的节点,然后去更改两个位置的指向关系,将新的节点指向关系理清楚就很容易模拟实现出insert了。 

完成了insert其实我们可以不用自己再实现push_back()和push_front()的,只需要对insert进行复用。

六、erase,pop_back,pop_front

删除pos位置也很简单,就是找到前一个位置和后一个位置,然后将它们链接起来就可以了。​​​​​​​注意要返回删除位置下一个的。

这样我们依旧可以复用erase来实现头删和尾删。

七、operator->

为什么operator->是这样实现呢,为什么返回T*呢,其实这里为了可读性省略了一个->,我们可以详细写出来,这样会比较清晰。

八、析构函数,拷贝构造函数,赋值重载,clear,swap

析构函数我们进行对clear的复用就可以了。

拷贝构造函数我们需要注意我们不能单纯的循环尾插,因为链表并没有构造出哨兵位的头节点,所以我们刚好可以实现一个空链表的初始化来复用。

接着我们来验证一下拷贝构造。

对于赋值重载我们依旧使用现代写法也就是复用库里面的swap。

http://www.xdnf.cn/news/17921.html

相关文章:

  • 推荐系统论文分享之多任务模型--PLE(二)
  • 内存可见性和伪共享问题
  • 【COMSOL】Comsol学习案例时的心得记录分享
  • nginx高性能web服务器实验
  • FPGA+护理:跨学科发展的探索(四)
  • 集成电路学习:什么是Image Processing图像处理
  • AI + 数字孪生:解锁物业 “立体透明” 新范式
  • 学习日志33 python
  • 第二十二天:指针与内存
  • 安全点(Safepoint)完成后唤醒暂停线程的过程
  • Ant Design 的 `Image` 组件,通过 `preview.src` 加载本地图片文件
  • 【3D渲染技术系列】AI 大模型贴图研究总结报告
  • 来伊份×养馋记:社区零售4.0模式加速渗透上海市场
  • Video_AVI_Packet(2)
  • EN 62368消费电子、信息技术设备和办公设备安全要求标准
  • 如何写出高质量的dify参数提取器prompt
  • 在JVM跑JavaScript脚本 | Oracle GraalJS 简介与实践
  • YOLO玩转目标检测(v5和v11两个版本)
  • 破解测试数据困境:5招兼顾安全与真实性
  • OpenBMC 中命令模式的深度解析:从原理到实现
  • CV 医学影像分类、分割、目标检测,之【腹腔多器官语义分割】项目拆解
  • 大厂语音合成成本深度对比:微软 / 阿里 / 腾讯 / 火山 API 计费拆解与技术选型指南
  • Java设计模式-责任链模式
  • 【力扣】面试经典150题总结02-双指针、滑动窗口
  • 如何在 Spring Boot 中设计和返回树形结构的组织和部门信息
  • 在线 A2C实践
  • Transformer模型实现与测试梳理
  • 深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构
  • 免费专业PDF文档扫描效果生成器
  • 海洋通信系统技术文档(1)