C++模拟实现——list

一、成员变量及其基本结构

1.基本结构模型

本质是一个带头双向循环列表,将节点进行封装,并且为了方便使用,进行重定义

2.节点的封装定义

	template<class T>//定义节点struct list_node{list_node<T>* _prev;list_node<T>* _next;T _data;list_node(const T& x = T()) :_prev(nullptr),_next(nullptr),_data(x){}};

在定义节点时,要注意将初始化一起进行封装完成,提供默认构造函数

3.成员变量的定义

成员变量是一个哨兵位的头结点

typedef list_node<T> node;//对节点重命名,方便使用
private:list_node<T>* _head;

二、迭代器(重点)

1.介绍

list的迭代器用原生指针无法实现,需要对原生指针进行封装,然后对顺序表指针的行为操作进行模拟实现,是list模拟实现中最大的重点难点,此时从使用者的角度上看,依然能将iterator看作为指针去使用,但设计者的角度上看,其本质是一个指针的封装,是个自定义类型。

2.对指针的基本封装

template<class T>
struct __list_iterator
{typedef list_node<int> node;//将节点重定义方便使用typedef __list_iterator<int> self;//将类型重定义方便使用//成员变量node* _node;//初始化__list_iterator(node* n):_node(n){}//模拟实现指针操作...
}

以上对节点指针进行了封装处理,之后逐一实现常用的功能,例如:++ 、--、* 、 -> 、== 、!= 等等

3.++和--

要提供迭代器++和--的操作,需要对运算符进行重载,链表迭代器的++本质上是获得下一个节点的地址,--则是前一个节点的地址,并且要区分前置和后置

        //++slef& operator++(){_node = _node->_next;return *this;}slef operator++(int)//后置{slef tmp(*this);_node = _node-> _next;return tmp;}//--self& operator--(){_node = _node->_prev;return *this;}self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}

4.== 和 !=

迭代器的比较,本质是要比较其封装在内部的指针是否同一个

bool operator!=(const self& n)
{return _node != n._node;
}bool operator==(const self& n)
{return _node == n._node;
}

5. * 和 ->

对解引用操作符的重载,则需要考虑到常量迭代器的调用,常量迭代器去本质是对迭代器所指向的内容进行常量化,因此在这里,const_iterator 和 iterator 的核心区别在于解引用后返回的值是否常量,其他功能相同,因此可以使用类模板去控制这两个运算符重载返回值的区别,在定义部分加上两个新的模板参数即可。

template<class T,class Ref,class Ptr>
strucr __list_iterator
{...//定义和重命名等等Ref operator*()//  Ref == T&(迭代器) / const T&(常量迭代器){return _node->_data;}//对于->的重载,存在特殊处理,只需要返回Ptr operator->()// Ptr == T*(迭代器)/ const T*(常量迭代器){return& _node->_data;}
}// 迭代器定义部分,在list类内定义
// typedef __list_iterator<T,T&,T*> iterator;
// typedef __list_con_iterator<T,const T&,const T*>;

三、构造与析构

1.默认构造函数

默认构造需要初始化出一个哨兵位的头结点,并且让节点指针指向自己,为了方便其他构造函数初始化哨兵位的头结点,可以单独写一个函数进行复用

		void empty_init(){_head = new node;_head->_next = _head;_head->_prev = _head;}list()//直接的初始化{empty_init();}

2.用迭代器区间去构造

迭代器区间构造需要借助函数模板,任意类型的迭代器都可以将值拷贝到容器中

template<class Iterator>
list(Iterator first,Iterator last)
{//先得初始化容器empty_init();while(first != last){push_back(*first); // 底层是++first;}
}

3.拷贝构造

拷贝构造这里选择对上面的构造函数进行复用,深拷贝出一个tmp,在进行交换

		void swap(list<T>& lt){std::swap(_head, lt._head);}list(const list<T>& lt)//拷贝构造{empty_init();list<T> tmp(lt.begin(), lt.end());swap(tmp);}

4.赋值重载

赋值重载的底层实现,也是在传参的时候,调用了拷贝构造实现深拷贝后,在进行交换

		list<T>& operator=(list<T> lt)//赋值重载{swap(lt);return *this;}

5.析构函数

可以先实现clear,然后复用,底层就是将所有节点全部逐一释放,用迭代器遍历释放即可

		void clear(){iterator it = begin();while (it != end()){it = erase(it);}}~list()//析构{clear();delete _head;_head = nullptr;}

四、增删操作

对应增删操作,只需要实现insert和erase,其余的头插头删等等都可以对其进行复用,这里是用迭代器去实现的。

		void insert(iterator pos, const T& x){node* cur = pos._node;node* prev = cur->_prev;node* new_node = new node(x);//链接new_node->_prev = prev;prev->_next = new_node;new_node->_next = cur;cur->_prev = new_node;}iterator erase(iterator pos){assert(pos != end());node* cur = pos._node;node* prev = cur->_prev;node* next = cur->_next;delete cur;//链接prev->_next = next;next->_prev = prev;return iterator(next);}

需要注意的是,erase后迭代器会失效,因此为了部分场景下的方便,erase是有一个返回值的,返回的是下一个节点的迭代器;

总结

本章通过自行模拟实现了list,加深了类和对象以及list的相关知识,其中很重要的一个知识点就是对与list迭代器的封装和实现,本篇博客整理了整个实现过程的思路,方便今后复习和其他同学参考学习

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

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

相关文章

【标准化封装 SOT系列 】 E SOT-89

〇、SOT-89 这个封装也比较常见&#xff0c;但并不易错。 一、E部分 SOT-89 参数 pin-pin 间距1.5mm body size 4.52.5 二、符合当前标准的典型举例 名称pin 数厂家 body DE矩形 (mm)SOT-894Mini-Circuits – PGA-102 — 4.39/4.62.29/2.59 上图 MiniCircuits 也称DF78…

C# Onnx Yolov8 Detect 路面坑洼检测

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Onnx…

线上答题活动小程序结合线下大屏复盘总结

线上答题活动小程序结合线下大屏复盘总结 ~ 说来话长&#xff0c;这个活动也接近尾声了&#xff0c;从刚开始着手开发&#xff0c;到现在已过去半年&#xff0c;好不夸张的&#xff0c;当时从4月份开始接触&#xff0c;现在已经十月份了 该小程序我发下主界面截图&#xff0…

MATLAB中 tf2zpk函数用法

目录 语法 说明 示例 IIR滤波器的极点、零点和增益 tf2zpk函数的功能是将传递函数滤波器参数转换为零极点增益形式。 语法 [z,p,k] tf2zpk(b,a) 说明 [z, p, k] tf2zpk(b, a) 从传递函数参数 b 和 a 中找到零点矩阵 z&#xff0c;极点向量 p&#xff0c;以及相关的增益…

C++类中函数重写(成员函数覆盖)

在本文中&#xff0c;您将学习函数重写。此外&#xff0c;您还将学习如何在C 编程中评估基类的函数重写。继承允许软件开发人员从现有类派生新类。派生类继承基类&#xff08;现有类&#xff09;的功能。假设基类和派生类都具有一个具有相同名称和参数&#xff08;参数的数量和…

C语言之排序

1.冒泡排序 冒泡排序就不多说了&#xff0c;只需要两层循环嵌套&#xff0c;两两比较确定相对正确的顺序即可。 2.插入排序 插入排序的思想就是每一次向后寻找一个再将其与前面有序的部分进行对比&#xff0c;寻找合适位置插入。 这里关键要避免让前移超出目前读取的数字&…

了解多媒体展厅弧幕投影系统收费构成,轻松制定预算

随着数字多媒体技术在内容展示行业中的广泛应用&#xff0c;基于投影、LED等技术手段的多媒体互动装置呈现多样化发展趋势&#xff0c;越来越多的新颖模式出现在大众眼前&#xff0c;其中就包括了备受关注的弧幕投影系统&#xff0c;作为投影技术显示形式的一种&#xff0c;它打…

1600*D. Maximum Sum on Even Positions(贪心)

Problem - 1373D - Codeforces 解析&#xff1a; 显然可以发现&#xff0c;翻转数量为奇数是不影响结果&#xff0c;所以需要反转偶数个连续数字。 考虑贪心&#xff0c;我们每次反转相邻的两个数字&#xff0c;并且累计贡献&#xff0c;如果贡献为0则清空继续累计&#xff0c;…

排序算法,冒泡排序算法及优化,选择排序SelectionSort,快速排序(递归-分区)

一、冒泡排序算法&#xff1a; 介绍&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单直观的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需…

MT8766核心板详细参数_MTK联发科4G安卓核心板智能通讯模块

MT8766安卓核心板采用四核2.0GHz主频芯片方案&#xff0c;国内4G全网通。12nm先进工艺&#xff0c;支持Android 9.0系统。GPU采用超强 IMG GE8300 。 可流畅适配大数据运算、人脸识别算法、多种识别模式。支持高速LPDDR4/X&#xff0c;主频高达1600MHz。支持EMMC5.1。标配 WIF…

聊聊分布式架构08——SpringBoot开启微服务时代

目录 微服务架构时代 快速入门 入门详解 SpringBoot的自动配置 石器时代&#xff1a;XML配置bean 青铜时代&#xff1a;SpringConfig 铁器时代&#xff1a;AutoConfigurationImportSelector 手写简单Starter SpringApplication启动原理 微服务架构时代 Spring Boot的…

[MAUI]深入了解.NET MAUI Blazor与Vue的混合开发

文章目录 Vue在混合开发中的特点创建MAUI项目创建Vue应用使用element-ui组件库JavaScript和原生代码的交互传递根组件参数从设备调用Javascript代码从Vue页面调用原生代码 读取设备信息项目地址 .NET MAUI结合Vue的混合开发可以使用更加熟悉的Vue的语法代替Blazor语法&#xff…

数据图册页面(左边一列图片缩略图,右边展示图片大图)

最近要写这么一个页面&#xff0c;左侧一列图片缩略图&#xff0c;点击左侧缩略图后有选中效果&#xff0c;然后右侧展示图片原图&#xff0c;还能够左右翻页查看。 最后写了一个demo出来&#xff0c;demo还不是很完善&#xff0c;需要自己修改&#xff0c;后面我也给出了修改建…

如何处理前端SEO(搜索引擎优化)?

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

第一节——vue安装+前端工程化

作者&#xff1a;尤雨溪 官网&#xff1a;简介 | Vue.js 脚手架文档 创建一个项目 | Vue CLI 一、概念&#xff08;了解&#xff09; 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&…

在Kubernetes(k8s)上部署整个SpringCloud微服务应用

视频教程地址&#xff1a;https://www.bilibili.com/video/BV1Xh4y1q7aW/ 文章目录 项目准备打成使用Docker打成镜像准备Docker仓库打包项目为Docker镜像 部署应用到k8s创建nfs挂载目录创建一些基本资源创建命名空间创建拉取镜像的secret创建java运行环境的profile 部署mysql创…

c++_learning-c++标准库STL和boost库

c的标准库 STL标准库&#xff1a;#include<iostream>&#xff1a;#include<iomanip>&#xff1a;#include<cstdlib>&#xff1a;#include<cmath>&#xff1a;#include<tuple>&#xff1a;利用可变参数模板&#xff0c;借助“递归继承”或“递归组…

Godot 官方2D C#重构(1):雪花碰撞

前言 Godot 官方 教程 Godot 2d 官方案例C#重构 专栏 Godot 2d 重构 github地址 实现效果 难点介绍 Godot GDScript和C# 对应关系大部分靠猜 文件导入 资源地址&#xff1a;默认为res://开头2D贴图导入类型&#xff1a;Texture2D public Texture2D Bullet_Image new Textu…

超全整理,服务端性能测试-tomcat部署项目/查看日志(细致)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 tomcat部署单项目…

TechSmith Camtasia Studio 23.3.2.49471 Crack

全新的Camtasia 2023.2 Camtasia Studio是专业的屏幕录像和视频编辑的软件套装。软件提供了强大的屏幕录像&#xff08;Camtasia Recorder&#xff09;、视频的剪辑和编辑&#xff08;Camtasia Studio&#xff09;、视频菜单制作&#xff08;Camtasia MenuMaker&#xff09;、视…