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。

相关推荐
平常心的技术小牛1 小时前
Qt-快速上手-QMenuBar
开发语言·qt
青 春 记 忆1 小时前
零基础入门Python11|Git实战:为任务管理器建立版本历史
开发语言·git·vscode·python·python3.11
余额瞒着我当琳3 小时前
C++--深拷贝三件套 + swap + 写时拷贝 + vector 扩容 + reserve
java·开发语言·c++
坐吃山猪4 小时前
WebClient内存配置解析
开发语言·springboot·webflux
jdksjw4 小时前
同步与异步、阻塞与非阻塞、多线程、协程超详细讲解(Python并发编程从入门到精通)
开发语言·python
Zach_菠萝侠4 小时前
【DeepSeek Harness 研究】进化方向4:安全加固 思考、设计与实现
开发语言·安全·deepseek
ShineWinsu4 小时前
对于C++:布隆过滤器(bloomfilter)的详细解析
c++·面试·位图·位运算·布隆过滤器·海量数据·比特位
SL-staff5 小时前
技术实践:HR如何用JVS-Logic可视化编排实现考勤数据同步(含节点配置与异常处理)
开发语言·python·低代码·钉钉·可视化编排·jvs-logic·hr技术
SomeB1oody5 小时前
【RustyML入门】6.0. 数学工具
开发语言·后端·机器学习·rust·教程
进制树6 小时前
【飞控开发实战·⑲】ROS2无人机开发环境搭建:Jazzy安装、工作空间与hello_drone节点实战
开发语言·安全·无人机·课程设计