【C++】STL中list的模拟实现(增删查改,迭代器封装,运算符重载)

news2024/9/24 1:26:30

文章目录

  • 前言
    • 大体框架:
  • 一、节点的封装(list_node)
  • 二、迭代器的封装(_list_iterator)
    • 1.类模板的定义:
    • 2.构造函数
    • 3.前置++,后置++
    • 4.前置--,后置--
    • 5.解引用(operator*())
    • 6. ->重载(operator- >())
    • 7.比较运算符的重载:
  • 三、list成员函数
    • 1.构造函数
    • 2.begin(),end()
    • 3.插入(insert)在pos之前一个位置插入
    • 4.删除(erase)
    • 5.尾插尾删
    • 6.头插头删
    • 7.析构函数
    • 8.赋值运算符重载
    • 9.拷贝构造函数
    • 10.大小(size)


前言

list的底层结构为带头结点的双向循环链表

大体框架:

namespace simulation {
	template <class T>
	struct list_node {
	//成员函数
	};
template<class T,class Ref,class Ptr>
	struct _list_iterator {
	//成员函数
	};

template<class T>
	class list {
		typedef list_node<T> Node;
	public:
		typedef _list_iterator<T, T&, T*> iterator;
		typedef _list_iterator<T, const T&, const T*>  const_iterator;
	//成员函数
		private:
		Node* _head;
		size_t _size;
	};
	}
	

一、节点的封装(list_node)

template <class T>
	struct list_node {
		//带头的双向循环链表
		//在类模板中:
		//类名不等于类型,所以定义指针时类名要显示实例化
		list_node<T>* _prev;
		list_node<T>* _next;
		T _val;
		list_node(const T&val=T())
			//T()相当于调用构造函数;
			:_prev(nullptr)
			,_next(nullptr)
			,_val(val)
		{}
	};

二、迭代器的封装(_list_iterator)

因为list的数据不是在一片连续的内存中(像vector,string那样)
所以我们不能用原生指针来当迭代器iterator,我们要自己设计一个
迭代器,自己去实现其++以及比较等操作

1.类模板的定义:

//设计const迭代器:可以把迭代器理解为类似指针
	// 错误示范: typedef const __list_iterator<T> const_iterator;
	// 这样设计const迭代器是不行的,因为const迭代器期望指向内容不能修改
	// 这样设计是迭代器本身不能修改
	 
	//为了设计不那么繁琐,我们传入三个模板参数
	template<class T,class Ref,class Ptr>
	//相当于:
	// typedef __list_iterator<T, T&, T*> iterator;
		// typedef __list_iterator<T, const T&, const T*> const_iterator;

2.构造函数

typedef list_node<T> Node;
		typedef _list_iterator<T, Ref, Ptr> self;
		Node* _node;//成员变量

		_list_iterator(Node* node)
			:_node(node)
		{}

3.前置++,后置++

self& operator++() {//前置++
		//typedef _list_iterator<T, Ref, Ptr> self;
			_node = _node->_next;
			return *this;
		}
		self operator++(int) {//后置++
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

4.前置–,后置–

self& operator--() {
			_node = _node->_prev;
			return *this;
		}
		self operator--(int) {
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

5.解引用(operator*())

Ref operator*() {
		//因为可能为const T&类型或者T&类型
		//为了避免繁琐,使用模板参数里面的Ref
		//编译器根据不同的类型会生成对应的函数
			return _node->_val;
		}

6. ->重载(operator- >())

    //template<class T,class Ref,class Ptr>
	//相当于:
	// typedef __list_iterator<T, T&, T*> iterator;
	// typedef __list_iterator<T, const T&, const T*> const_iterator;
Ptr operator->() {
			return&_node->_val;
		}

在这里插入图片描述

7.比较运算符的重载:

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

三、list成员函数

1.构造函数

typedef list_node<T> Node;
	public:
		typedef _list_iterator<T, T&, T*> iterator;
		typedef _list_iterator<T, const T&, const T*>  const_iterator;
		void empty_init() {
			_size = 0;
			_head = new Node;
			_head->_prev = _head;
			_head->_next = _head;
		}
		list() {//构造函数
			empty_init();
		}
   private:
         Node*_head;//哨兵位
         size_t _size;

2.begin(),end()

         iterator begin() {
         //begin()为哨兵位下一个
			return _head->_next;
		}
		const_iterator begin()const {
			return _head->_next;
		}
		//end()为哨兵位
		iterator end() {
			return _head;
		}
		const_iterator end()const {
			return _head;
		}

3.插入(insert)在pos之前一个位置插入

在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

iterator insert(iterator pos, const T& x) {
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* newnode = new Node(x);
			newnode->_prev = prev;
			newnode->_next = cur;
			prev->_next = newnode;
			cur->_prev = newnode;
			++_size;

			//返回指向第一个新插入元素的迭代器。
			return newnode;
		}

4.删除(erase)

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;
			--_size;
			//返回被删除节点的下一个位置
			return next;
		}

5.尾插尾删

	void push_front(const T& x) {
			insert(begin(), x);
		}
		void pop_back() {
			erase(--end());
		}

6.头插头删

void push_back(const T&x) {
			insert(end(), x);
		}
void pop_front() {
			erase(begin());
		}

7.析构函数

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

8.赋值运算符重载

void swap(list<T>&lt){
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);
		}
		list<T>operator=(list<T> lt) {
			swap(lt);
			return *this;
		}

9.拷贝构造函数

     list(const list<T>& lt) {
			empty_init();
			_size = lt._size;
			for (auto &ch : lt) {
				push_back(ch);
			}
			
		}

10.大小(size)

size_t size() {
			return _size;
		}

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

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

相关文章

代码随想录算法学习心得 49 | 647.回文子串、516.最长回文子序列...

一、最长回文子序列 链接&#xff1a;力扣 描述&#xff1a;给你一个字符串 s &#xff0c;找出其中最长的回文子序列&#xff0c;并返回该序列的长度。 子序列定义为&#xff1a;不改变剩余字符顺序的情况下&#xff0c;删除某些字符或者不删除任何字符形成的一个序列。 思…

练习时长两年半的入侵检测

计算机安全的三大中心目标是&#xff1a;保密性 (Conf idential ity) 、完整性 (Integrity) 、可用性 (Availability) 。 身份认证与识别、访问控制机制、加密技术、防火墙技术等技术共同特征就是集中在系统的自身加固和防护上&#xff0c;属于静态的安全防御技术&#xff0c;…

将Python远控隐藏在文档图片中的行动分析

1、概述 ** **近日&#xff0c;安天CERT通过网络安全监测发现了一起恶意文档释放Python编写的远控木马事件。通过文档内容中涉及的组织信息和其中攻击者设置的诱导提示&#xff0c;安天CERT判断该事件是一起针对阿塞拜疆共和国国家石油公司进行的定向攻击活动。此次事件中&…

单线程与多线程的理解与学习(入门到深入)

文章目录 一、在Java中&#xff0c;有多种方式可以创建线程。以下是几种常用的方法&#xff1a;二、线程的调度线程的调度分为两种调度模型分时调度模型抢占式调度模型 三、线程传值四、什么是线程同步五、线程安全六、线程的同步机制七、线程控制 一、在Java中&#xff0c;有多…

惠普HP Color Laser 150a开机红色感叹号闪烁不打印故障解决方法

故障描述&#xff1a; 惠普HP Color Laser 150a开机红色感叹号闪烁&#xff0c;不能打印&#xff0c;电脑提示C3-6140。 检测分析&#xff1a; 在解决C3-6140错误代码之前&#xff0c;我们需要先检查打印机是否连接正常。如果打印机连接不正常&#xff0c;也可能会出现这个错误…

mysql_2.4——安装常见问题

1. 将MySQL添加到环境变量 将 mysql 的 bin 目录地址添加到 系统环境变量 --> PATH 中 2. 将MySQL添加到服务 以管理员的方式启动 cmd (命令提示窗口)&#xff0c;使用命令进入到 [mysql]\bin &#xff0c;执行如下命 令。 # mysqld --install (服务名) # 如: mysqld --…

SQL注入实操Less21-30)

文章目录 一、sqli-lab靶场1.轮子模式总结2.Less-21a.注入点判断b.轮子测试c.获取数据库名称d.获取表信息e.获取列信息f.获取表内数据 3.Less-22a.注入点判断b.轮子测试c.获取数据库名称d.获取表信息e.获取列信息f.获取表内数据 4.Less-23a.注入点判断b.轮子测试c.获取数据库名…

questasim界面的个性化设置

安装好questasim后默认的波形查看界面字体很小&#xff0c;颜色看起来也不舒服&#xff0c;所以调整了一下颜色布局如下图&#xff0c;顺便记录一下波形窗口颜色大小及选中行高亮如何设置 ​​​​​​​ 1、波形字体颜色设置 参考如何设置一个清爽的仿真窗口&#xff08;仿真…

【无标题】linux就该这么学

linux就该这么学 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注脚…

杰哥教你用Python对Emotet投递的恶意Excel表格提取IoCs

背景介绍 工作遇到多个经过同样方式混淆并隐藏的宏代码文档&#xff0c;利用Excel表格特性&#xff0c;将数据分离在不同的单元格中&#xff0c;再使用Office自带的函数对单元格的数值进行提取后组合成代码字符串运行。运行的代码完成下载恶意文件到本地并注册为服务的恶意行为…

spring项目中idea提示Application context not configured for this file

今天在重构项目的时候&#xff0c;碰到一个问题。就是在spring底下&#xff0c;有一个包里面的所有配置类&#xff0c;在idea的开发工具类底下提示&#xff0c;Application context not configured for this file&#xff0c;如图所示 一开始以为是警告&#xff0c;不予处理&am…

04 linux之C 语言高级编程

gcc和gdb GNU工具 编译工具&#xff1a;把一个源程序编译为一个可执行程序调试工具&#xff1a;能对执行程序进行源码或汇编级调试软件工程工具&#xff1a;用于协助多人开发或大型软件项目的管理&#xff0c;如make、CVS、Subvision其他工具&#xff1a;用于把多个目标文件链…

《入门级-Cocos2d 4.0塔防游戏开发》---第二课:游戏加载界面开发

一、开发环境介绍 操作系统&#xff1a;UOS1060专业版本。 cocos2dx:版本 环境搭建教程&#xff1a; 统信UOS下配置安装cocos2dx开发环境_三雷科技的博客-CSDN博客 二、开发内容 游戏在开始时都需要加载大量的资源&#xff0c;为了让用户有等待时间&#xff0c;因此最先开…

linux学成之路(基础篇)(二十三)MySQL服务(数据库备份——补充)

目录 一、MySQL数据库备份 概述 重要性 造成数据丢失的原因 二、备份类型 一、物理与逻辑角度 一、物理备份 二、逻辑备份 二、数据库备份策略角度 一、完整备份 二、增量备份 三、常见的备份方法 一、物理备份 二、使用专用备份工具 三、通过启用二进制日志增量…

漏洞发现-Xray+Awvs联动-Goby+Xray+Awvs+Vulmap联动

Acunetix: Acunetix一款商业的Web漏洞扫描程序&#xff0c;它可以检查Web应用程序中的漏洞&#xff0c;如SQL注入、跨站脚本攻击、身份验证页上的弱口令长度等。它拥有一个操作方便的图形用户界面&#xff0c;并且能够创建专业级的Web站点安全审核报告。新版本集成了漏洞管理功…

在家构建您的迷你 ChatGPT

这篇文章分为三个部分&#xff1b;他们是&#xff1a; 什么是指令遵循模型&#xff1f;如何查找遵循模型的指令构建一个简单的聊天机器人废话不多说直接开始吧&#xff01;&#xff01;&#xff01; 什么是指令遵循模型&#xff1f; 语言模型是机器学习模型&#xff0c;可以根…

移动开发之Wifi列表获取功能

一、场景 业务需要通过App给设备配置无线网络连接&#xff0c;所以需要App获取附近的WiFi列表&#xff0c;并进行网络连接验证。 二、安卓端实现 1、阅读谷歌官网文档&#xff0c;关于Wifi 接口使用 https://developer.android.com/guide/topics/connectivity/wifi-scan?hl…

SpringBoot——内置数据库

简单介绍 关于数据层的三大组件&#xff0c;数据源&#xff0c;持久化技术&#xff0c;数据库。前两种都已经介绍过了SpringBoot的内置的解决方案&#xff0c;还有最后一个数据库&#xff0c;在SpringBoot中&#xff0c;内置了三款数据库。分别是&#xff1a; H2HSQLDerby 这…

ARTIF:一种先进的实时威胁智能识别框架

关于ARTIF ARTIF是一个新型的高级实时威胁智能框架&#xff0c;它基于MISP并添加了另一个抽象层&#xff0c;以实现根据IP地址和历史数据识别恶意Web流量。除此之外&#xff0c;该工具还可以通过收集、处理和关联基于不同因素的观测值来执行自动分析和威胁评分。 功能介绍 评…

uni-app在小米手机上运行【步骤细节】

注意细节重点&#xff1a; 1.手机使用数据线与电脑连接&#xff0c;手机连接模式必须是传输文件模式 2.手机必须打开开发者模式 3.打开开发者模式后&#xff0c;仔细浏览并调整USB调试权限&#xff0c;重点打开USB是否允许安装按钮&#xff01;&#xff01;&#xff01; 操作步…