C++初阶——简单实现list

目录

1、前言

2、List.h

3、Test.cpp


1、前言

1. 简单实现std::list,重点:迭代器,模板类,运算符重载。

2. 并不是,所有的类,都需要深拷贝,像迭代器类模板,只是用别的类的资源,不需要深拷贝。

3. 高度相似 -> 模板。

4. 迭代器的种类

功能:iterator,reverse_iterator,const_iterator,const_reverse_iterator。

按结构(性质):决定可以使用什么算法

单向(Forward):forward_list/unordered_map/unordered_set    ++

双向(Bidirectional):list/map/set    ++/--

随机(Random Access):vector/string/deque    ++/--/+/-

2、List.h

#pragma once#include <iostream>
#include <list>
#include <assert.h>using namespace std;namespace Lzc
{template<class T>struct list_node{typedef list_node<T> Node;T _data;Node* _next;Node* _prev;list_node(const T& data = T()):_data(data), _next(nullptr), _prev(nullptr){}};//template<class T>//struct list_iterator//{//	typedef list_node<T> Node;//	typedef list_iterator<T> iterator;//	Node* _node;//	list_iterator(Node* node)//		:_node(node)//	{}//	T& operator*() const//	{//		return _node->_data;//	}//	T* operator->() const//	{//		return &_node->_data;//	}//	iterator& operator++() // 前置++//	{//		_node = _node->_next;//		return *this;//	}//	iterator operator++(int) // 后置++//	{//		iterator tmp(_node);//		_node = _node->_next;//		return tmp;//	}//	iterator& operator--() // 前置--//	{//		_node = _node->_prev;//		return *this;//	}//	iterator operator--(int) // 后置--//	{//		iterator tmp(_node);//		_node = _node->_prev;//		return tmp;//	}//	bool operator!=(const iterator& it) const//	{//		return _node != it._node;//	}//  bool operator==(const iterator& it) const//	{//		return _node == it._node;//	}//};//template<class T>//struct list_const_iterator//{//	typedef list_node<T> Node;//	typedef list_const_iterator<T> const_iterator;//	Node* _node;//	list_const_iterator(Node* node)//		:_node(node)//	{//	}//	const T& operator*() const//	{//		return _node->_data;//	}//	const T* operator->() const//	{//		return &_node->_data;//	}//	const_iterator& operator++() // 前置++//	{//		_node = _node->_next;//		return *this;//	}//	const_iterator operator++(int) // 后置++//	{//		iterator tmp(_node);//		_node = _node->_next;//		return tmp;//	}//	const_iterator& operator--() // 前置--//	{//		_node = _node->_prev;//		return *this;//	}//	const_iterator operator--(int) // 后置--//	{//		iterator tmp(_node);//		_node = _node->_prev;//		return tmp;//	}//	bool operator!=(const const_iterator& it) const//	{//		return _node != it._node;//	}// 	bool operator==(const const_iterator& it) const//	{//		return _node == it._node;//	}//};// 高度相似->模板template<class T, class Ref, class Ptr>struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, Ref, Ptr> Self;Node* _node;list_iterator(Node* node) // 就是要指针,浅拷贝,没问题:_node(node){}Ref operator*() const{return _node->_data;}Ptr operator->() const{return &_node->_data;}Self& operator++() // 前置++{_node = _node->_next;return *this;}Self operator++(int) // 后置++{Self tmp(_node);_node = _node->_next;return tmp;}Self& operator--() // 前置--{_node = _node->_prev;return *this;}Self operator--(int) // 后置--{Self tmp(_node);_node = _node->_prev;return tmp;}bool operator!=(const Self& it) const{return _node != it._node;}bool operator==(const Self& it) const{return _node == it._node;}};template<class T>class list{typedef list_node<T> Node; // 只有list类的成员函数或者友元才能使用这个类型别名public:typedef list_iterator<T, T&, T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;//typedef list_iterator<T> iterator;//typedef list_const_iterator<T> const_iterator;iterator begin(){return _head->_next; // 隐式类型转换}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_initialize(){_head = new Node;_head->_next = _head->_prev = _head;_size = 0;}list(){empty_initialize();}list(initializer_list<T> lt){empty_initialize();for (auto& e : lt){push_back(e);}}list(const list& lt){// list();构造函数不能被直接调用empty_initialize();for (auto& e : lt){push_back(e);}}void swap(list& tmp){std::swap(_head, tmp._head);std::swap(_size, tmp._size);}list& operator=(const list& lt){list tmp(lt);swap(tmp);return *this;}void clear(){while (!empty()){pop_front();}}~list(){clear();delete _head;_head = nullptr;_size = 0;}size_t size() const{return _size;}bool empty() const{return _size == 0;}void push_back(const T& val){insert(end(), val);}void push_front(const T& val){insert(begin(), val);}iterator insert(iterator pos, const T& val);void pop_front(){erase(begin());}void pop_back(){erase(_head->_prev);}iterator erase(iterator pos);private:Node* _head;size_t _size;};template<class T>typename list<T>::iterator list<T>::insert(iterator pos, const T& val){Node* newNode = new Node(val);Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newNode;newNode->_prev = prev;newNode->_next = cur;cur->_prev = newNode;++_size;return newNode;}template<class T>typename list<T>::iterator list<T>::erase(iterator pos){assert(pos != _head);Node* cur = pos._node;Node* next = cur->_next;Node* prev = cur->_prev;prev->_next = next;next->_prev = prev;delete cur;--_size;return next;}template<class Container>void print_Container(const Container& con){for (auto& e : con){cout << e << " ";}cout << endl;}
}

3、Test.cpp

#include "List.h"namespace Lzc
{struct AA{int _a1 = 1;int _a2 = 1;};void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;print_Container(lt);list<AA> lta;lta.push_back(AA());lta.push_back(AA());lta.push_back(AA());lta.push_back(AA());list<AA>::iterator ita = lta.begin();while (ita != lta.end()){//cout << (*ita)._a1 << ":" << (*ita)._a2 << endl;cout << ita->_a1 << ":" << ita->_a2 << endl;// 特殊处理,本来应该是两个->才合理,为了可读性,省略了一个->// cout << ita.operator->()->_a1 << ":" << ita.operator->()->_a2 << endl;++ita;}cout << endl;}void test_list2(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);// insert后,it还指向begin(),没有扩容的概念,不失效list<int>::iterator it = lt.begin();lt.insert(it, 10); *it += 100;print_Container(lt);// erase后,it为野指针,及时更新// 删除所有的偶数it = lt.begin();while (it != lt.end()){if (*it % 2 == 0){it = lt.erase(it);}else{++it;}}print_Container(lt);}void test_list3(){list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);list<int> lt2(lt1);print_Container(lt1);print_Container(lt2);list<int> lt3;lt3.push_back(10);lt3.push_back(20);lt3.push_back(30);lt3.push_back(40);lt1 = lt3;print_Container(lt1);print_Container(lt3);}void func(const list<int>& lt){print_Container(lt);}void test_list4(){// 直接构造list<int> lt0({ 1,2,3,4,5,6 });// 隐式类型转换list<int> lt1 = { 1,2,3,4,5,6,7,8 };const list<int>& lt3 = { 1,2,3,4,5,6,7,8 };func(lt0);func({ 1,2,3,4,5,6 });print_Container(lt1);// template<class T> class initializer_list;// { 10, 20, 30 }是一种initializer_list<int>类型//auto il = { 10, 20, 30 };//initializer_list<int> il = { 10, 20, 30 };//cout << typeid(il).name() << endl;//cout << sizeof(il) << endl;}
}int main()
{Lzc::test_list1();Lzc::test_list2();Lzc::test_list3();Lzc::test_list4();return 0;
}

注意:声明和定义分离时,为什么定义时,是list<T>::iterator,不是iterator,因为iterator在list<T>中typedef了,就属于list<T>的成员变量了。

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

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

相关文章

conda环境中运行“python --version“所得的版本与环境中的python版本不一致----deepseek并非全能

conda环境中运行python —version所得python版本与conda环境中的python版本不一致------deepseek并非全能 问题 conda环境中运行python —version所得python版本与conda环境中的python版本不一致 我所做的探索 1 网页搜索 2 求助于DeepSeek 可以用四个字来形容deepseek给出…

HarmonyOS学习第5天: Hello World的诞生之旅

鸿蒙初印象&#xff1a;开启探索之门 在操作系统的广袤天地中&#xff0c;HarmonyOS&#xff08;鸿蒙系统&#xff09;宛如一颗冉冉升起的新星&#xff0c;自诞生起便备受瞩目。它由华为倾力打造&#xff0c;是一款基于微内核的全场景分布式操作系统&#xff0c;以其独特的技术…

centos9安装k8s集群

以下是基于CentOS Stream 9的Kubernetes 1.28.2完整安装流程&#xff08;containerd版&#xff09;&#xff1a; 一、系统初始化&#xff08;所有节点执行&#xff09; # 关闭防火墙 systemctl disable --now firewalld# 关闭SELinux sed -i "s/SELINUXenforcing/SELINU…

CIG容器重量级监控系统

1.介绍 CAdvisorinfluxDBGranfana docker 原生命令 监控docker容器状态 docker stats 2.CAdvicsor 3.InfluxDB 4.Granafana 5.搭建 volumes:grafana_data: services:influxdb:image: tutum/influxdbrestart: alwaysenvironment:- PRE_CREATE_DBcadvisorports:- "8083…

REACT学习DAY02(恨连接不上服务器)

受控表单绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 1. 准备一个React状态值 const [value,setValue] useState() 2. 通过value属性绑定状态&#xff0c;通过onChange属性绑定状态同步的函数 <input type"text&quo…

python——GUI图形用户界面编程

GUI简介 我们前面实现的都是基于控制台的程序&#xff0c;程序和用户的交互通过控制台来完成 本章&#xff0c;我们来学习GUI图形用户界面编程&#xff0c;我们可以通过python提供的丰富的组件&#xff0c;快速的视线使用图形界面和用户交互 GUI变成类似于“搭积木”&#x…

DeepSeek 助力 Vue 开发:打造丝滑的单选按钮(Radio Button)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

美颜相机1.0

项目开发步骤 1 界面开发 美颜相机界面构成&#xff1a; 标题 尺寸 关闭方式 位置 可视化 2 创建主函数调用界面方法 3 添加两个面板 一个是按钮面板一个是图片面板 用JPanel 4 添加按钮到按钮面吧【注意&#xff1a;此时要用初始化按钮面板的方法initBtnPanel 并且将按钮添…

openharmony中hdf框架的驱动消息机制的实现原理

openharmony中hdf框架的驱动消息机制的实现原理 在分析hdf框架时发现绕来绕去的&#xff0c;整体梳理画了一遍流程图&#xff0c;发现还是有点模糊甚至不清楚如何使用的&#xff0c;详细的每个点都去剖析细节又过于消耗时间&#xff0c;所以有时间便从功能应用的角度一块块的去…

leaflet实现历史轨迹播放效果

效果图如下&#xff1a; 效果实现&#xff1a; 1、添加完整轨迹线&#xff0c;蓝色的 this.echoLine L.polyline(points, { weight: 8 }).addTo(this.map) 2、添加实时轨迹线&#xff0c;初始状态置空 this.realEchoLine L.polyline([], { weight: 12, color: "#FF9…

JAVAEE一>Spring IoC和DI详解

目录 Spring容器说明&#xff1a;Ioc容器优势&#xff1a;DI介绍&#xff1a;从Spring获取对象&#xff1a;获取对象的方法&#xff1a;关于上下文的概念&#xff1a; Controller注解&#xff08;控制层&#xff1a;接收参数并响应&#xff09;&#xff1a;Service注解&#xf…

(四)趣学设计模式 之 原型模式!

目录 一、 啥是原型模式&#xff1f;二、 为什么要用原型模式&#xff1f;三、 原型模式怎么实现&#xff1f;四、 原型模式的应用场景五、 原型模式的优点和缺点六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xf…

完美解决:.vmx 配置文件是由 VMware 产品创建,但该产品与此版 VMware Workstation 不兼容

参考文章&#xff1a;该产品与此版 VMware Workstation 不兼容&#xff0c;因此无法使用 问题描述 当尝试使用 VMware Workstation 打开别人的虚拟机时&#xff0c;可能会遇到以下报错&#xff1a; 此问题常见于以下场景&#xff1a; 从其他 VMware 版本&#xff08;如 ESX…

Linux——安装Git的方法

安装Git的命令&#xff1a; yum -y install git查看Git的版本&#xff1a; git --version

编程小白冲Kaggle每日打卡(13)--kaggle学堂:<机器学习简介>基础数据探索

Kaggle官方课程链接&#xff1a;Basic Data Exploration 本专栏旨在Kaggle官方课程的汉化&#xff0c;让大家更方便地看懂。 Basic Data Exploration 加载并理解您的数据。 使用Pandas熟悉您的数据 任何机器学习项目的第一步都是熟悉数据。您将使用Pandas库进行此操作。Pand…

从零开始的网站搭建(以照片/文本/视频信息通信网站为例)

本文面向已经有一些编程基础&#xff08;会至少一门编程语言&#xff0c;比如python&#xff09;&#xff0c;但是没有搭建过web应用的人群&#xff0c;会写得尽量细致。重点介绍流程和部署云端的步骤&#xff0c;具体javascript代码怎么写之类的&#xff0c;这里不会涉及。 搭…

【Java项目】基于SpringBoot的【高校校园点餐系统】

【Java项目】基于SpringBoot的【高校校园点餐系统】 技术简介&#xff1a;采用Java技术、MySQL数据库、B/S结构实现。 系统简介&#xff1a;高校校园点餐系统是一个面向高校师生的在线点餐平台&#xff0c;主要分为前台和后台两大模块。前台功能模块包括&#xff08;1&#xff…

Django check_password原理

check_password 是 Django 提供的一个用于密码校验的函数&#xff0c;它的工作原理是基于密码哈希算法的特性。 Django 的 make_password 函数在生成密码哈希时&#xff0c;会使用一个随机的 salt&#xff08;盐值&#xff09;。这个 salt 会与密码一起进行哈希运算&#xff0…

Vulnhun靶机-kioptix level 4-sql注入万能密码拿到权限ssh连接利用mysql-udf漏洞提权

目录 一、环境搭建信息收集扫描ip扫描开放端口扫描版本服务信息指纹探测目录扫描 二、Web渗透sql注入 三、提权UDF提权修改权限 一、环境搭建 然后选择靶机所在文件夹 信息收集 本靶机ip和攻击机ip 攻击机&#xff1a;192.168.108.130 靶机&#xff1a;192.168.108.141 扫描…

PHP 会话(Session)实现用户登陆功能

Cookie是一种在客户端和服务器之间传递数据的机制。它是由服务器发送给客户端的小型文本文件&#xff0c;保存在客户端的浏览器中。每当浏览器向同一服务器发送请求时&#xff0c;它会自动将相关的Cookie信息包含在请求中&#xff0c;以便服务器可以使用这些信息来提供个性化的…