《STL--list的使用及其底层实现》
引言:
上次我们学习了容器vector
的使用及其底层实现,今天我们再来学习一个容器list
,
这里的list
可以参考我们之前实现的单链表,但是这里的list
是双向循环带头链表,下面我们就开始list
的学习了。
一:list
的介绍
list的介绍文档:
二:list
的使用
1. 约定:
关于list
的接口众多,下面我们只介绍一些比较常用的接口,其他接口同学们可以自行去list
的介绍文档中学习。
2. list的构造:
- list (size_type n, const value_type& val =value_type()):构造的
list
中包含n
个值为val
的元素。 - list():构造空的
list
。 - list (const list& x):拷贝构造函数。
- list (InputIterator first, InputIterator last):用
[first, last)
区间中的元素构造
list
。
代码演示:
3.list iterator
的使用
注:这里大家先将list的迭代器理解为指向节点的一个指针。
- begin:返回第一个元素的迭代器。
- end:返回最后一个元素下一个位置的迭代器。
- rbegin:返回第一个元素的
reverse_iterator
,即end
位置。 - rend:返回最后一个元素下一个位置的
reverse_iterator
,即begin
位置。
代码演示:
注:
begin
与end
为正向迭代器,对迭代器执行++
操作,迭代器向后移动rbegin(end)
与rend(begin)
为反向迭代器,对迭代器执行++
操作,迭代器向前移动
4.list capacity
的使用
- empty:检测
list
是否为空,为空返回true
,反之则返回false
。 - size:计算
list
中有效数据的个数。
代码演示:
5. list element access
- front:返回
list
的第一个节点中值的引用。 - back:返回
list
的最后一个节点中值的引用。
代码演示:
6. list modifiers
- push_front:在
list
首元素前插入值为val
的元素。 - pop_front:删除
list
中第一个元素。 - push_back:在
list
尾部插入值为val
的元素。 - pop_back:删除
list
中最后一个元素。 - insert:在
list position
位置中插入值为val
的元素。 - erase:删除
list position
位置的元素。 - swap:交换两个
list
中的元素。 - clear:清空
list
中的有效元素。
代码演示:
(1)push_back(front)
pop_back(front)
(2)erase
和insert
swap
和clear
7. list
迭代器失效问题
前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list
的底层结构为带头结点的双向循环链表,因此在list
中进行插入时是不会导致list
的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
这里想要解决迭代器失效的话,处理方式和之前是一样的,需要对其重新进行赋值:
三:list
的模拟实现
1. 思考:
这里在模拟实现list
时就和vector
的实现有所区别了,之前实现的vector
的本质上一个数组,其迭代器和原生指针没什么区别,对其迭代器解引用就可以拿到对应的数据,但是这里的list
里面存储的是一个个节点,因此这里的迭代器并不是单纯的原生指针,你对节点指针解引用的话拿到的是一个节点,并不能直接拿到节点里的数据,但是这不是我们期望的,按照我们的逻辑是解引用节点指针是要拿到这个节点指针对应节点里面的数据,因此这里在模拟实现的时候就比之前要复杂一点,牵扯到迭代器的构造以及有关迭代器的一些重载。
2.基本框架:
(1)节点结构:
(2)迭代器结构:
(3)链表结构:
3. 迭代器结构完善
(1)*
重载:
(2) 前置++和后置++重载:
(3) 前置- - 和后置 - - 重载:
(4) 比较运算符重载:
4. 构造函数
注:这里在构造的过程中由于会对e进行解引用,因此这里要用引用。
5. begin
和 end
6. insert
函数
注:由于这里除了数据的申请,其他的逻辑和之前实现的双向链表没啥区别,就不细讲了。
7. push_back
函数
注:这里就直接复用insert
即可。
8. push_front
函数
9. erase
函数
注:
- 这里需要注意头结点我们是不能动的。(大哥动不得)
- 为解决
erase
引起的迭代器失效问题,这里我们的erase
给了返回值。
10. pop_back
函数
注:这里就是直接复用erase
即可。
11. pop_front
函数
12. clear
函数
13. 析构函数
14. size
函数
注:为了避免重复遍历链表来计算个数,因此这里我们就来维护一个成员变量_size
,因此之前的插入和删除都需要维护_size
15. swap
函数
四: 拷贝构造函数引起的问题及解决方案
1. 问题的引发
我们这里在实现拷贝构造函数的时候出现了以下问题:
那么为什么会出现这个问题呢?
2. 思考:
因为拷贝构造函数这里给的参数是const
类类型,但是这里在构造的过程中用到了范围for
,我们知道,范围for
本质上就是迭代器的替换,并且因为需要进行解引用,所以这里的范围for我们用的是引用,但是由于传入参数是const
类型,这里需要const
类型的迭代器来支持,所以这里才会出现问题,因此我们就需要实现const
类型的迭代器。
3. 解决方案:
这里由于const
迭代器和普通类型的迭代器就一点不同,如果再封装一个类的话就太冗余了,因此这里就可以从模版下手:
这个时候就解决了上面出现的问题,而且这样使得我们在使用不同的迭代器时编译器能够自动推导类型。
4. 赋值运算符重载:
五:补充内容— -> 重载
1. 引入:
首先我们来看vector
存储自定义类型时的访问:
下面再来看用list
来存储自定义类型时的访问:
可以看到用list
来存储自定义类型的时候就不能用->
来访问,这是为什么呢?
还是回到前面提到的迭代器的区别,vector
的迭代器就可以理解为原生指针,用->
就可以拿到其里面的数据,而list
这里的迭代器->
的话拿到的是节点,而不是数据,因此,这里这样写就有问题,那么我们看一下标准库里面的list的->
:
可以看到标准库里面的list
就可以通过->
来访问数据,这是因为标准库里的list
对->
进行了特殊处理,因此我们这里也需要对->
进行重载才可以。
2. ->
重载:
注:这里->
的重载看着就有点奇怪了,注意这里返回的是指向数据的指针(数据的地址)
注意这里的两种写法都可以,第一种方式只是编译器对其进行了特殊处理,其实第二种写法更符合我们理解的逻辑。
完结!!!
相关文章:

《STL--list的使用及其底层实现》
引言: 上次我们学习了容器vector的使用及其底层实现,今天我们再来学习一个容器list, 这里的list可以参考我们之前实现的单链表,但是这里的list是双向循环带头链表,下面我们就开始list的学习了。 一:list的…...
whisper相关的开源项目 (asr)
基于 Whisper(OpenAI 的开源语音识别模型)的开源项目有很多,涵盖了不同应用场景和优化方向。以下是一些值得关注的项目: 1. 核心工具 & 增强版 Whisper OpenAI Whisper 由 OpenAI 开源的通用语音识别模型,支持多语…...

python的pip怎么配置的国内镜像
以下是配置pip国内镜像源的详细方法: 常用国内镜像源列表 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple阿里云:https://mirrors.aliyun.com/pypi/simple中科大:https://pypi.mirrors.ustc.edu.cn/simple华为云࿱…...

PCB 通孔是电容性的,但不一定是电容器
哼?……这是什么意思?…… 多年来,流行的观点是 PCB 通孔本质上是电容性的,因此可以用集总电容器进行建模。虽然当信号的上升时间大于或等于过孔不连续性延迟的 3 倍时,这可能是正确的,但我将向您展示为什…...
领域驱动设计与COLA框架:从理论到实践的落地之路
目录 引言 DDD核心概念 什么是领域驱动设计 DDD的核心概念 1. 统一语言(Ubiquitous Language) 2. 限界上下文(Bounded Context) 3. 实体(Entity)与值对象(Value Object) 4. 聚…...

公有云AWS基础架构与核心服务:从概念到实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 (初学者技术专栏) 一、基础概念 定义:AWS(Amazon Web Services)是亚马逊提供的云计算服务&a…...

Python60日基础学习打卡D35
import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler import time import matplotlib.pyplot as plt# 设置GPU设…...
Python经典算法实战
在编程的世界里,算法是解决问题的灵魂,而Python以其简洁优雅的语法成为实现算法的理想语言。无论你是初学者还是有一定经验的开发者,《Python经典算法实战》都能带你深入算法的殿堂,从理论到实践,一步步构建起扎实的编…...
spring+tomcat 用户每次发请求,tomcat 站在线程的角度是如何处理用户请求的,spinrg的bean 是共享的吗
对于 springtomcat 用户每次发请求,tomcat 站在线程的角度是如何处理的 比如 bio nio apr 等情况 tomcat 配置文件中 maxThreads 的数量是相对于谁来说的? 以及 spring Controller 中的全局变量:各种bean 对于线程来说是共享的吗? 一、Tomca…...

目标检测 RT-DETR(2023)详细解读
文章目录 主干网络:Encoder:不确定性最小Query选择Decoder网络: 将DETR扩展到实时场景,提高了模型的检测速度。网络架构分为三部分组成:主干网络、混合编码器、带有辅助预测头的变换器编码器。具体来说,先利…...

微信小程序 隐私协议弹窗授权
开发微信小程序的第一步往往是隐私协议授权,尤其是在涉及用户隐私数据时,必须确保用户明确知晓并同意相关隐私政策。我们才可以开发后续的小程序内容。友友们在按照文档开发时可能会遇到一些问题,我把所有的授权方法和可能遇到的问题都整理出…...
题目 3325: 蓝桥杯2025年第十六届省赛真题-2025 图形
题目 3325: 蓝桥杯2025年第十六届省赛真题-2025 图形 时间限制: 2s 内存限制: 192MB 提交: 494 解决: 206 题目描述 小蓝要画一个 2025 图形。图形的形状为一个 h w 的矩形,其中 h 表示图形的高,w 表示图形的宽。当 h 5,w 10 时,图形如下所…...

金众诚业财一体化解决方案如何提升项目盈利能力?
在工程项目管理领域,复杂的全生命周期管理、成本控制的精准性以及业务与财务的高效协同,是决定项目盈利能力的核心要素。随着数字化转型的深入,传统的项目管理方式已难以满足企业对效率、透明度和盈利能力的需求。基于金蝶云星空平台打造的金…...
bitbar环境搭建(ruby 2.4 + rails 5.0.2)
此博客为武汉大学WA学院网络安全课程,理论课大作业Web环境搭建。 博主搭了2天!!!血泪教训是还是不能太相信ppt上的教程。 一开始尝试了ppt上的教程,然后又转而寻找网络资源 cs155源代码和docker配置,做到…...
从零起步搭建基于华为云构建碳排放设备管理系统的产品设计
目录 🌿 华为云 IoT:轻松上手碳排放设备管理系统搭建 🌍 逐步搭建搭建规划 🚀 一、系统蓝图:5大核心模块,循序渐进 1️⃣ 设备管理与数据采集层 2️⃣ 数据传输与协议转换层 3️⃣ 数据处理与分析层…...

LabVIEW中EtherCAT从站拓扑离线创建及信息查询
该 VI 主要用于演示如何离线创建 EtherCAT 从站拓扑结构,并查询从站相关信息。EtherCAT(以太网控制自动化技术)是基于以太网的实时工业通信协议,凭借其高速、高效的特性在自动化领域广泛应用。与其他常见工业通讯协议相比…...
SpringBoot-11-基于注解和XML方式的SpringBoot应用场景对比
文章目录 1 基于注解的方式1.1 @Mapper1.2 @select1.3 @insert1.4 @update1.5 @delete2 基于XML的方式2.1 namespace2.2 resultMap2.3 select2.4 insert2.5 update2.6 delete3 service和controller3.1 service3.2 controller4 注解和xml的选择如果SQL简单且项目规模较小,推荐使…...

Flutter 3.32 新特性
2天前,Flutter发布了最新版本3.32,我们来一起看下29到32有哪些变化。 简介 欢迎来到Flutter 3.32!此版本包含了旨在加速开发和增强应用程序的功能。准备好在网络上进行热加载,令人惊叹的原生保真Cupertino,以及与Fir…...
前端面试热门知识点总结
URL从输入到页面展示的过程 版本1 1.用户在浏览器的地址栏输入访问的URL地址。浏览器会先根据这个URL查看浏览器缓存-系统缓存-路由器缓存,若缓存中有,直接跳到第6步操作,若没有,则按照下面的步骤进行操作。 2.浏览器根据输入的UR…...

windows和mac安装虚拟机-详细教程
简介 虚拟机:Virtual Machine,虚拟化技术的一种,通过软件模拟的、具有完整硬件功能的、运行在一个完全隔离的环境中的计算机。 在学习linux系统的时候,需要安装虚拟机,在虚拟机上来运行操作系统,因为我使…...
【Hive 开发进阶】窗口函数深度解析:OVER/NTILE/RANK 实战案例与行转列高级技巧
一、窗口函数 OVER 详解 窗口函数用于在分组内进行数据排名、聚合计算等操作,语法格式: 函数名() over([partition by 分组字段] [order by 排序字段] [window子句])案例:员工信息与部门平均工资 create table emp (id int,dept string,sa…...
在STM32上配置图像处理库
在STM32上配置并使用简单的图像滤波库(以实现均值滤波为例,不依赖复杂的大型图像处理库,方便理解和在资源有限的STM32上运行)为例,给出代码示例,使用STM32CubeIDE开发环境和HAL库,假设已经初始化好了相关GPIO和DMA(如果有图像数据传输需求),并且图像数据存储在一个二…...

【C++】vector容器实现
目录 一、vector的成员变量 二、vector手动实现 (1)构造 (2)析构 (3)尾插 (4)扩容 (5)[ ]运算符重载 5.1 迭代器的实现: (6&…...
RocketMQ 深度解析:消息中间件核心原理与实践指南
一、RocketMQ 概述 1.1 什么是 RocketMQ RocketMQ 是阿里巴巴开源的一款分布式消息中间件,后捐赠给 Apache 基金会成为顶级项目。它具有低延迟、高并发、高可用、高可靠等特点,广泛应用于订单交易、消息推送、流计算、IoT 等场景。 1.2 核心特性 高吞…...

使用Docker Compose部署Dify
目录 1. 克隆项目代码2. 准备配置文件3. 配置环境变量4. 启动服务5. 验证部署6. 访问服务注意事项 1. 克隆项目代码 首先,克隆Dify项目的1.4.0版本: git clone https://github.com/langgenius/dify.git --branch 1.4.02. 准备配置文件 进入docker目录…...
基于 Vue3 与 exceljs 实现自定义导出 Excel 模板
在开发中,我们需要常常为用户提供更多的数据录入方式,Excel 模板导出与导入是一个常见的功能点。本文将介绍如何使用 Vue3、exceljs 和 file-saver 实现一个自定义导出 Excel 模板,并在特定列添加下拉框选择的数据验证功能。 技术选型 excelj…...

杰发科技AC7840——CSE硬件加密模块使用(1)
1. 简介 2. 功能概述 3. 简单的代码分析 测试第二个代码例程 初始化随机数 这里的CSE_CMD_RND在FuncID中体现了 CSE_SECRET_KEY在17个用户KEY中体现 最后的读取RNG值,可以看出计算结果在PRAM中。 总的来看 和示例说明一样,CSE 初次使用,添加…...

前端地图数据格式标准及应用
前端地图数据格式标准及应用 坐标系EPSGgeojson标准格式基于OGC标准的地图服务shapefile文件3D模型数据常见地图框架 坐标系EPSG EPSG(European Petroleum Survey Group)是一个国际组织,负责维护和管理地理坐标系统和投影系统的标准化编码 E…...

threejs几何体BufferGeometry顶点
1. 几何体顶点位置数据和点模型 本章节主要目的是给大家讲解几何体geometry的顶点概念,相对偏底层一些,不过掌握以后,你更容易深入理解Threejs的几何体和模型对象。 缓冲类型几何体BufferGeometry threejs的长方体BoxGeometry、球体SphereGeometry等几…...

向量数据库选型实战指南:Milvus架构深度解析与技术对比
导读:随着大语言模型和AI应用的快速普及,传统数据库在处理高维向量数据时面临的性能瓶颈日益凸显。当文档经过嵌入模型处理生成768到1536维的向量后,传统B-Tree索引的检索效率会出现显著下降,而现代应用对毫秒级响应的严苛要求使得…...