《STL--list的使用及其底层实现》

news2025/5/27 14:02:53

引言:

上次我们学习了容器vector的使用及其底层实现,今天我们再来学习一个容器list
这里的list可以参考我们之前实现的单链表,但是这里的list双向循环带头链表,下面我们就开始list的学习了。

一:list的介绍

list的介绍文档:

二:list的使用

1. 约定:

关于list的接口众多,下面我们只介绍一些比较常用的接口,其他接口同学们可以自行去list的介绍文档中学习。

2. list的构造:

  1. list (size_type n, const value_type& val =value_type()):构造的list中包含n个值为val的元素。
  2. list():构造空的list
  3. list (const list& x):拷贝构造函数。
  4. list (InputIterator first, InputIterator last):[first, last)区间中的元素构造
    list
代码演示:

在这里插入图片描述

3.list iterator的使用

注:这里大家先将list的迭代器理解为指向节点的一个指针。

  1. begin:返回第一个元素的迭代器。
  2. end:返回最后一个元素下一个位置的迭代器。
  3. rbegin:返回第一个元素的reverse_iterator,即end位置。
  4. rend:返回最后一个元素下一个位置的reverse_iterator,即begin位置。
代码演示:

在这里插入图片描述
注:

  1. beginend为正向迭代器,对迭代器执行++操作,迭代器向后移动
  2. rbegin(end)rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

4.list capacity的使用

  1. empty:检测list是否为空,为空返回true,反之则返回false
  2. size:计算list中有效数据的个数。
代码演示:

在这里插入图片描述

5. list element access

  1. front:返回list的第一个节点中值的引用。
  2. back:返回list的最后一个节点中值的引用。
代码演示:

在这里插入图片描述

6. list modifiers

  1. push_front:list首元素前插入值为val的元素。
  2. pop_front:删除list中第一个元素。
  3. push_back:list尾部插入值为val的元素。
  4. pop_back:删除list中最后一个元素。
  5. insert:list position 位置中插入值为val的元素。
  6. erase:删除list position位置的元素。
  7. swap:交换两个list中的元素。
  8. clear:清空list中的有效元素。
代码演示:
(1)push_back(front) pop_back(front)

在这里插入图片描述

(2)eraseinsert

在这里插入图片描述
在这里插入图片描述

swapclear

在这里插入图片描述
在这里插入图片描述

7. list迭代器失效问题

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

在这里插入图片描述

这里想要解决迭代器失效的话,处理方式和之前是一样的,需要对其重新进行赋值:

在这里插入图片描述

三:list的模拟实现

1. 思考:

这里在模拟实现list时就和vector的实现有所区别了,之前实现的vector的本质上一个数组,其迭代器和原生指针没什么区别,对其迭代器解引用就可以拿到对应的数据,但是这里的list里面存储的是一个个节点,因此这里的迭代器并不是单纯的原生指针,你对节点指针解引用的话拿到的是一个节点,并不能直接拿到节点里的数据,但是这不是我们期望的,按照我们的逻辑是解引用节点指针是要拿到这个节点指针对应节点里面的数据,因此这里在模拟实现的时候就比之前要复杂一点,牵扯到迭代器的构造以及有关迭代器的一些重载。

2.基本框架:

(1)节点结构:

在这里插入图片描述

(2)迭代器结构:

在这里插入图片描述

(3)链表结构:

在这里插入图片描述

3. 迭代器结构完善

(1)* 重载:

在这里插入图片描述

(2) 前置++和后置++重载:

在这里插入图片描述

(3) 前置- - 和后置 - - 重载:

在这里插入图片描述

(4) 比较运算符重载:

在这里插入图片描述

4. 构造函数

在这里插入图片描述
注:这里在构造的过程中由于会对e进行解引用,因此这里要用引用。

5. beginend

在这里插入图片描述

6. insert 函数

在这里插入图片描述
注:由于这里除了数据的申请,其他的逻辑和之前实现的双向链表没啥区别,就不细讲了。

7. push_back 函数

在这里插入图片描述
注:这里就直接复用insert即可。

8. push_front 函数

在这里插入图片描述

9. erase 函数

在这里插入图片描述
注:

  1. 这里需要注意头结点我们是不能动的。(大哥动不得
  2. 为解决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. -> 重载:

在这里插入图片描述
:这里->的重载看着就有点奇怪了,注意这里返回的是指向数据的指针(数据的地址)
在这里插入图片描述
在这里插入图片描述
注意这里的两种写法都可以,第一种方式只是编译器对其进行了特殊处理,其实第二种写法更符合我们理解的逻辑。

完结!!!

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

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

相关文章

python的pip怎么配置的国内镜像

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

PCB 通孔是电容性的,但不一定是电容器

哼?……这是什么意思?…… 多年来,流行的观点是 PCB 通孔本质上是电容性的,因此可以用集总电容器进行建模。虽然当信号的上升时间大于或等于过孔不连续性延迟的 3 倍时,这可能是正确的,但我将向您展示为什…

公有云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设…

目标检测 RT-DETR(2023)详细解读

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

微信小程序 隐私协议弹窗授权

开发微信小程序的第一步往往是隐私协议授权,尤其是在涉及用户隐私数据时,必须确保用户明确知晓并同意相关隐私政策。我们才可以开发后续的小程序内容。友友们在按照文档开发时可能会遇到一些问题,我把所有的授权方法和可能遇到的问题都整理出…

金众诚业财一体化解决方案如何提升项目盈利能力?

在工程项目管理领域,复杂的全生命周期管理、成本控制的精准性以及业务与财务的高效协同,是决定项目盈利能力的核心要素。随着数字化转型的深入,传统的项目管理方式已难以满足企业对效率、透明度和盈利能力的需求。基于金蝶云星空平台打造的金…

LabVIEW中EtherCAT从站拓扑离线创建及信息查询

该 VI 主要用于演示如何离线创建 EtherCAT 从站拓扑结构,并查询从站相关信息。EtherCAT(以太网控制自动化技术)是基于以太网的实时工业通信协议,凭借其高速、高效的特性在自动化领域广泛应用。与其他常见工业通讯协议相比&#xf…

Flutter 3.32 新特性

2天前,Flutter发布了最新版本3.32,我们来一起看下29到32有哪些变化。 简介 欢迎来到Flutter 3.32!此版本包含了旨在加速开发和增强应用程序的功能。准备好在网络上进行热加载,令人惊叹的原生保真Cupertino,以及与Fir…

windows和mac安装虚拟机-详细教程

简介 虚拟机:Virtual Machine,虚拟化技术的一种,通过软件模拟的、具有完整硬件功能的、运行在一个完全隔离的环境中的计算机。 在学习linux系统的时候,需要安装虚拟机,在虚拟机上来运行操作系统,因为我使…

【C++】vector容器实现

目录 一、vector的成员变量 二、vector手动实现 (1)构造 (2)析构 (3)尾插 (4)扩容 (5)[ ]运算符重载 5.1 迭代器的实现: (6&…

使用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目录…

杰发科技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索引的检索效率会出现显著下降,而现代应用对毫秒级响应的严苛要求使得…

java方法重写学习笔记

方法重写介绍 子类和父类有两个返回值,参数,名称都一样的方法, 子类的方法会覆盖父类的方法。 调用 public class Overide01 {public static void main(String[] args) {Dog dog new Dog();dog.cry();} }Animal类 public class Animal {…

TensorBoard安装与基本操作指南(PyTorch)

文章目录 什么是TensorBoard?TensorBoardX与TensorBoard的依赖关系易混关系辨析Pytorch安装TensorBoard并验证1. TensorBoard安装和访问2. TensorBoard主要界面介绍实用技巧 什么是TensorBoard? TensorBoard是TensorFlow生态系统中的一款强大的可视化工…

2025/5/25 学习日记 linux进阶命令学习

tree:以树状结构显示目录下的文件和子目录,方便直观查看文件系统结构。 -d:仅显示目录,不显示文件。-L [层数]:限制显示的目录层级(如 -L 2 表示显示当前目录下 2 层子目录)。-h:以人类可读的格…

【MPC控制 - 从ACC到自动驾驶】4 MPC的“实战演练”:ACC Simulink仿真与结果深度解读

【MPC控制 - 从ACC到自动驾驶】MPC的“实战演练”:ACC Simulink仿真与结果深度解读 在过去的几天里,我们一起: Day 1: 认识了ACC这位聪明的“跟车小能手”和MPC这位“深谋远虑的棋手”。Day 2: 给汽车“画了像”,建立了它的纵向…