list 简化版模拟实现

 1ListNode

template<class T>
	struct ListNode
	{
	public:
		ListNode(const T& x = T())
			:_next(nullptr)
			, _prev(nullptr)
			, _data(x)
		{}
		//private:
			//共有可访问
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;
	};

 实现iterator对Node*的封装  实现运算符重载

 

void const_print(const MyList::list<int>& lt)//这里的const本意是lt的node中的data不可改,却使lt不可改
//const迭代器是指, it已经封装过,把it当作指向node中的data的指针    it内的_node 的
{
	MyList::list<int>::const_iterator it = lt.begin();//所以应该是 通过函数重载,返回一个迭代器,不能支持对(*it)的改动
	while (it != lt.end())
	{
		//报错,必须是可修改的左值  *it += 19;
		//*it += 19;
		cout << (*it) << ' ';
		it++;
	}
	cout << endl;
}

 2ListIterator

template<class T, class Ref, class Ptr>
	class ListIterator
	{
	public:
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;//变化
		ListIterator(Node* node)
			:_node(node)
		{}
		Ref operator*()//变化
		{
			return _node->_data;
		}
		Ptr operator->()//变化
		{
			return &(_node->_data);
		}
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		Self operator++(int)
		{
			Self 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;
		}
		bool operator!=(Self it)
		{
			return _node != it._node;
		}
		//private:   共有
		Node* _node;
	};

 3list

template<class T>
	class list
	{
	public:
		typedef ListNode<T> Node;
		//typedef ListIterator<T> iterator;
		//typedef ListConstIterator<T> const_iterator;//但这样要实现两个类 可以合并

		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&, const  T*> const_iterator;

		iterator begin()//头是head下一个节点
		{
			return _head->_next;//单参数的自定义类型支持隐式类型转化  c++11对于多参数的也可以{xx,xx,xx}
		}
		iterator end()//尾是head
		{
			return _head;
		}
		const_iterator begin()const//直接加const 对于const对象能调用,然后刚好构成函数重载,
		{
			return _head->_next;//返回值也不能是 const itertor 这指的是it不能改,应该封装成(*it)不可改
		}
		const_iterator end()const
		{
			return _head;
		}
		void empty_init()
		{
			//先new一个节点
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		list(initializer_list<T>il)
		{
			empty_init();
			for (auto& e : il)
				push_back(e);
		}
		list()
		{
			empty_init();
		}
		list(const list<T>& lt)
		{
			empty_init();
			for (auto& i : lt)//要引用 有可能是自定义类型
			{
				push_back(i);
			}
		}
		/*void push_back(const T& x)
		{
			Node* newnode = new Node(x);
			Node* tail = _head->_prev;

			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;
		}*/
		void push_back(const T& x)
		{
			insert(end(), x);
		}
		void push_front(const T& x)
		{
			insert(begin(), x);
		}
		void pop_back()
		{
			erase(--end());//不能是-1,没有重载
		}
		void pop_front()
		{
			erase(begin());
		}
		void insert(iterator pos, T val)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* newnode = new Node(val);

			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;
		}
		iterator erase(iterator pos)//迭代器失效  返回next
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			prev->_next = next;
			next->_prev = prev;

			delete cur;//
			return iterator(next);
		}
		size_t size()
		{
			size_t sz = 0;
			for (auto i : (*this))
				sz++;
			return sz;
		}
		bool empty()
		{
			return size() == 0;
		}
		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}
		~list()
		{
			clear();
			delete _head;
		}
	private:
		Node* _head;
	};

 4对于const迭代器的解释和->操作符重载

struct A
{
	int _a1;
	int _a2;
	A(int a1 = 0, int a2 = 0)
		:_a1(a1)
		, _a2(a2)
	{}
};
void const_print(const MyList::list<int>& lt)//这里的const本意是lt的node中的data不可改,却使lt不可改(
//const迭代器是指, it已经封装过,把it当作指向node中的data的指针    
{
	MyList::list<int>::const_iterator it = lt.begin();//所以应该是 通过函数重载,返回一个迭代器,不能支持对(*it)的改动
	while (it != lt.end())
	{
		//报错,必须是可修改的左值  *it += 19;
		//*it += 19;
		cout << (*it) << ' ';
		it++;
	}
	cout << endl;
}
void print(MyList::list<int>& lt)
{
	MyList::list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		*it += 19;
		cout << (*it) << ' ';
		it++;
	}
	cout << endl;
}
void test2()
{
	MyList::list<A>lt;
	lt.push_back({ 1,2 });//隐式类型转换,c++11
	lt.push_back({ 1,2 });
	lt.push_back({ 1,2 });
	MyList::list<A>::iterator it = lt.begin();
	while (it != lt.end())
	{
		//报错cout << (*it) << " ";//(*it)访问的是 节点的数据 对于int 数据就是int 支持流输出 ,这里是A对象
		//其实就是把it当作 指向A的指针,但本质不是    (*it)就是A  
		//就是(*it)经过封装,(*it)就是A  ,,但it->没封装
		//cout << (*it)._a1 << "." << (*it)._a2<<endl;//但本应该it->data  要支持->重载  返回值是_data *
		cout << it->_a1 << "." << it->_a2 << endl;
		it++;
	}
	cout << endl;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入理解DES算法:原理、实现与应用

title: 深入理解DES算法&#xff1a;原理、实现与应用 date: 2024/4/14 21:30:21 updated: 2024/4/14 21:30:21 tags: DES加密对称加密分组密码密钥管理S盒P盒安全性分析替代算法 DES算法简介 历史 DES&#xff08;Data Encryption Standard&#xff09;算法是由IBM研发&…

整数在内存中的存储和内存操作函数

目录 整数在内存中的存储1. 整数在内存中的存储2. 大小端字节序和字节序判断2.1 什么是大小端?2.2 为什么有大小端 3. 练习3.1 请简述大端字节序和小端字节序的概念&#xff0c;设计⼀个小程序来判断当前机器的字节序。&#xff08;10分&#xff09;-百度笔试题3.2 练习23.3 练…

科研学习|科研软件——如何使用SmartPLS软件进行结构方程建模

SmartPLS是一种用于结构方程建模&#xff08;SEM&#xff09;的软件&#xff0c;它可以用于定量研究&#xff0c;尤其是在商业和社会科学领域中&#xff0c;如市场研究、管理研究、心理学研究等。 一、准备数据 在使用SmartPLS之前&#xff0c;您需要准备一个符合要求的数据集。…

Vector - CAPL - XCP介绍_02

前面我们介绍了关于使用vector XCP License后&#xff0c;通过CAPL对XCP协议进行连接、断开和获取当前XCP连接状态的函数&#xff0c;本篇文章不做过多的其他赘述&#xff0c;我们继续介绍CAPL控制XCP相关的其他函数。 目录 xcpActivate 代码示例 xcpDeactivate xcpActiva…

【周总结】

周总结 完成工单脚本的编写以及解决操作问题 完成相关 jira 问题修改 学习了 sentinel 整合项目使用流控&#xff0c;熔断&#xff0c;热点等功能的使用 2024/4/14 晴 1. 这周只办两件事&#xff0c;吃&#xff01;喝&#xff01;&#xff01;&#xff01; 2.忙忙忙&am…

开源博客项目Blog .NET Core源码学习(15:App.Hosting项目结构分析-3)

本文学习并分析App.Hosting项目中前台页面的关于本站页面和点点滴滴页面。 关于本站页面 关于本站页面相对而言布局简单&#xff0c;与后台控制器类的交互也不算复杂。整个页面主要使用了layui中的面包屑导航、选项卡、模版、流加载等样式或模块。   面包屑导航。使用layui…

Web前端 Javascript笔记3

1、垃圾回收机制 内存中的生命周期 1、内存分配 2、内存使用&#xff08;读写&#xff09; 3、内存回收&#xff0c;使用完毕之后&#xff0c;垃圾回收器完成 内存泄漏&#xff1a;该回收的&#xff0c;由于某些未知因素&#xff0c;未释放&#xff0c;叫做内存泄漏 栈&#xf…

PostgreSQL入门到实战-第二十九弹

PostgreSQL入门到实战 PostgreSQL中数据分组操作(四)官网地址PostgreSQL概述PostgreSQL中CUBE命令理论PostgreSQL中CUBE命令实战更新计划 PostgreSQL中数据分组操作(四) 如何使用PostgreSQL CUBE生成多个分组集 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不…

Linux配置程序后台运行(前后台来回切换)

Linux配置程序后台运行 在日常开发过程中&#xff0c;会遇到我们在前台运行程序&#xff0c;此时我们临时有事&#xff0c;但不能关闭终端&#xff0c;否则程序就会在电脑熄屏&#xff08;终端session断开后&#xff09;停止运行。 那么作为一个合格的开发&#xff0c;就必须要…

Matlab 2024安装教程(附免费安装包资源)

鼠标右击软件压缩包&#xff0c;选择“解压到MatlabR2024a“。 2.打开解压后的文件夹&#xff0c;鼠标右击“MATHWORKS_R2024A“选择装载。 鼠标右击“setup“选择”以管理员身份运行“。点击“是“&#xff0c;然后点击”下一步“。复制一下密钥粘贴至输入栏&#xff0c;然后…

数据结构——双向链表的实现

文章目录 一、双向链表的结构二、实现双向链表创建双向链表的项目双向链表的结构List.h申请结点初始化打印尾插头插尾删头删查找在pos位置之后插入数据删除pos结点销毁 三、所有源代码List.hList.ctest.c 一、双向链表的结构 带头双向循环链表 注意&#xff1a;这⾥的“带头…

数据交换格式

一、什么是数据交换格式 在计算机的不同程序之间&#xff0c;或者不同的编程语言之间进行交换数据&#xff0c;也需要一种大家都能听得懂得‘语言’&#xff0c;这就是数据交换格式&#xff0c;它通过文本以特定的形式来进行描述数据。 二、常用的几种数据交换格式 客户端常…

图像处理ASIC设计方法 笔记17 连通域的图像标记算法

目录 (一)主要环节图像初步标记 -等价表初始化与等价关系记录 -整理等价表 -图像标记代换 -(二)详细算法步骤:1 等价表的操作:2 整理等价表:3 图像标记代换:连通域的图像标记算法有若干步骤,除了图像初步标记,还有等价表初始化、等价关系记录、整理等价表、图像标记代…

【C++】深度解析---赋值运算符重载(小白一看就懂!!)

目录 一、前言 二、 运算符重载 &#x1f34e;运算符重载 ① 概念引入 ② 语法明细 ③ 练习巩固 ④ 代码展示 &#x1f347;赋值运算符重载 ① 语法说明及注意事项 ② 默认的赋值运算符重载 ③ 值运算符不能重载成全局函数&#xff01; 三、总结 四、共勉 一、前言…

前端console用法分享

console对于前端人员来讲肯定都不陌生&#xff0c;相信大部分开发者都会使用console来进行调试&#xff0c;但它能做的绝不仅限于调试。 最常见的控制台方法 作为开发者&#xff0c;最常用的 console 方法如下&#xff1a; 控制台打印结果&#xff1a; 今天我分享的是一些 co…

Qt快速入门(MV架构之TableView + QStandardItemModel + 自定义代理小案例)

Qt快速入门&#xff08;MV架构之TableView QStandardItemModel 自定义代理小案例&#xff09; 关于MV架构的简单介绍 在Qt框架中&#xff0c;代理&#xff08;Delegate&#xff09;、模型&#xff08;Model&#xff09;和视图&#xff08;View&#xff09;之间的关系构成了…

jvisualVM分析jvm内存使用快照dump

服务发生内存溢出&#xff0c;就需要查看服务器上Java服务的jvm堆内存使用情况&#xff0c;可以使用dump命令生成dump文件&#xff0c;然后下载到本地&#xff0c;然后使用jvisualVM工具打开&#xff0c;即可实现可视化分析。 生成dump文件常用的两种方式&#xff1a; 第一种…

linux fixmap分析

本文基于Linux-4.19.125&#xff0c; ARM V7&#xff0c;dual core, MMU采用2级页表&#xff08;未开启LPAE&#xff09;。 1 为什么需要fixmap Linux内核启动过程中&#xff0c;经过汇编阶段后&#xff0c;mmu功能已经开启&#xff0c;后续只能通过虚拟地址来访问DDR&#x…

RAG应用开发实战02-相似性检索的关键 - Embedding

1 文本Embedding 将整个文本转化为实数向量的技术。 Embedding优点是可将离散的词语或句子转化为连续的向量&#xff0c;就可用数学方法来处理词语或句子&#xff0c;捕捉到文本的语义信息&#xff0c;文本和文本的关系信息。 ◉ 优质的Embedding通常会让语义相似的文本在空…

Linux 添加启动服务--Service

1&#xff0c;服务配置service文件 Service 服务的实际作用是开启后自动启动服务&#xff0c;运行一些不须要登录的程序&#xff0c;任务。 实例1、上电自动连接WIFI热点 1.1 新建.service文件 /etc/systemd/system/wificonnect.service [Unit] DescriptionService [wifico…