当前位置: 首页 > article >正文

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>的成员变量了。

相关文章:

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

目录 1、前言 2、List.h 3、Test.cpp 1、前言 1. 简单实现std::list&#xff0c;重点&#xff1a;迭代器&#xff0c;类模板&#xff0c;运算符重载。 2. 并不是&#xff0c;所有的类&#xff0c;都需要深拷贝&#xff0c;像迭代器类模板&#xff0c;只是用别的类的资源&am…...

linux 命令+相关配置记录(持续更新...)

linux 命令记录相关配置记录 磁盘切换 cd D&#xff1a;#这里表示切换到D盘查看wsl 安装的linux 子系统 wsl --list -vwsl 卸载 linux 子系统 wsl --unregister -xxx # xxx 表示子系统的名字备份Linux 子系统 导出 wsl --export xxx yyy # xxx 表示子系统的名字 yyy 表示压…...

【PDF预览】使用iframe实现pdf文件预览,加盖章

使用iframe实现pdf文件预览&#xff0c;以及在pdf上添加水印。另外还包括批注、打印、下载、缩放、分页等功能 <iframesrc"http://static.shanhuxueyuan.com/test.pdf"width"100%"height"100%"frameborder"0"></iframe>&l…...

网络运维学习笔记(DeepSeek优化版)002网工初级(HCIA-Datacom与CCNA-EI)子网划分与协议解析

文章目录 子网划分与协议解析1. VLSM与CIDR技术解析1.1 VLSM&#xff08;Variable Length Subnetwork Mask&#xff0c;可变长子网掩码&#xff09;1.2 CIDR&#xff08;Classless Inter-Domain Routing&#xff0c;无类域间路由&#xff09; 2. 子网划分方法与计算2.1 常规划分…...

在线骑行|基于SpringBoot的在线骑行网站设计与实现(源码+数据库+文档)

在线骑行网站系统 目录 基于SpringBoot的在线骑行设计与实现 一、前言 二、系统设计 三、系统功能设计 5.1用户信息管理 5.2 路线攻略管理 5.3路线类型管理 5.4新闻赛事管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取…...

BUUCTF-Web方向21-25wp

目录 [HCTF 2018]admin弱口令session伪造 [MRCTF2020]你传你&#x1f40e;呢[护网杯 2018]easy_tornado[ZJCTF 2019]NiZhuanSiWei[MRCTF2020]Ez_bypass第一层第二层 [HCTF 2018]admin 打开环境&#xff0c;有三处提示&#xff0c;一个跳转链接&#xff0c;一个登录注册&#x…...

软考——WWW与HTTP

1.万维网&#xff08;world wide web&#xff09; 是一个规模巨大的、可以资源互联的资料空间。由URL进行定位&#xff0c;通过HTTP协议传送给使用者&#xff0c;又由HTML来进行文件的展现。 它的主要组成部分是&#xff1a;URL、HTTP、HTML。 &#xff08;1&#xff09;URL…...

GO 进行编译时插桩,实现零码注入

Go 编译时插桩 Go 语言的编译时插桩是一种在编译阶段自动注入监控代码的技术&#xff0c;目的是在不修改业务代码的情况下&#xff0c;实现对应用程序的监控和追踪。 基本原理 Go 编译时插桩的核心思想是通过在编译过程中对源代码进行分析和修改&#xff0c;将监控代码注入到…...

为人工智能驱动的交通研究增强路面传感器数据采集

论文标题 英文标题&#xff1a;Enhancing Pavement Sensor Data Harvesting for AI-Driven Transportation Studies 中文标题&#xff1a;为人工智能驱动的交通研究增强路面传感器数据采集 作者信息 Manish Kumar Krishne Gowda Purdue University, 465 Northwestern Avenue,…...

unordered_set和unordered_map的使用

Hello&#xff0c;今天我来为大家介绍一下前几年才刚刚新出的两个容器——unordered_map和unordered_set&#xff0c;这两个容器属于是map系列和set系列中的一种&#xff0c;和map/set不同的是它们的底层&#xff0c;map/set的底层是红黑树&#xff0c;而unordered_map/unorder…...

【实体类】分层设计

【实体类】分层设计 【一】实体类的PO、VO、DO、DAO、BO、DTO、POJO有什么区别【1】PO&#xff08;Persistent Object&#xff09;【2】VO&#xff08;View Object&#xff09;【3】DO&#xff08;Domain Object&#xff09;【4】DAO&#xff08;Data Access Object&#xff09…...

【无人集群系列---无人机集群编队算法】

【无人集群系列---无人机集群编队算法】 一、核心目标二、主流编队控制方法1. 领航-跟随法&#xff08;Leader-Follower&#xff09;2. 虚拟结构法&#xff08;Virtual Structure&#xff09;3. 行为法&#xff08;Behavior-Based&#xff09;4. 人工势场法&#xff08;Artific…...

C语言基本知识------指针(4)

1. 回调函数是什么&#xff1f; 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另⼀个函数&#xff0c;当这个指针被⽤来调⽤其所指向的函数 时&#xff0c;被调⽤的函数就是回调函数。 void qsort(void base,//指针…...

深度学习pytorch之19种优化算法(optimizer)解析

提示&#xff1a;有谬误请指正 摘要 本博客详细介绍了多种常见的深度学习优化算法&#xff0c;包括经典的LBFGS 、Rprop 、Adagrad、RMSprop 、Adadelta 、ASGD 、Adamax、Adam、AdamW、NAdam、RAdam以及SparseAdam等&#xff0c;通过对这些算法的公式和参数说明进行详细解析…...

使用 BFS 解决 最短路问题

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 目录 1926.迷宫中离入口最近的出口 433.最小基因变化 127.单词接龙 675.为高尔夫比赛砍树 1926.迷宫中离入口最近的出口 题…...

【嵌入式Linux应用开发基础】网络编程(1):TCP/IP协议栈

目录 一、TCP/IP协议栈分层与核心协议 2.1. 应用层 2.2. 传输层 2.3. 网络层 2.4. 链路层 二、嵌入式Socket编程关键步骤 2.1. TCP服务端流程 2.2. TCP客户端流程 三、TCP/IP协议栈的配置与调试 四、嵌入式场景优化策略 4.1. 资源管理 4.2. 性能调优 4.3. 健壮性保…...

OpenCalib(七)二维码检测

1. 前言 前面无论是对棋盘格标靶还是圆形标靶检测时,一般都需要将所有标靶全部检出,这样才能根据标靶的分布确定每个标靶的相对位置。举个例子,对于5x5分布的棋盘格,如果我们只检出4x4排列的棋盘格,那么它在整个棋盘格中可能存在4种分布,此时我们无法确认检测结果中各个棋…...

DeepSeek在初创企业、教育和数字营销领域应用思考

如今&#xff0c;像 DeepSeek 这样的人工智能工具正在改变企业的运营方式&#xff0c;优化流程并显著提高生产力。通过重复任务的自动化、大量数据的分析以及内容创建效率的提高&#xff0c;组织正在寻找新的竞争和卓越方式。本文介绍了 DeepSeek 如何用于提高三个关键领域的生…...

BUUCTF--[极客大挑战 2019]RCE ME

目录 URL编码取反绕过 异或绕过 异或的代码 flag 借助蚁剑中的插件进行绕过 利用动态链接库 编写恶意c语言代码 进行编译 然后再写一个php文件 将这两个文件上传到/var/tmp下 运行payload 直接看代码 <?php error_reporting(0); if(isset($_GET[code])){$code$_G…...

【K8s】专题十六(2):Kubernetes 包管理工具之 Helm 使用

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 | 精选文章 | Kubernetes | Docker | Linux | 羊毛资源 | 工具推荐 | 往期精彩文章 【Docker】&#xff08;全…...

使用anaconda装虚拟环境

1. 下载好anaconda, 可以参考 笔记 2. 创建虚拟环境 # 创建新环境 # &#xff08;Conda 允许创建任意 Python 版本的环境&#xff0c;与基础环境无关。&#xff09; # 需要指定python版本&#xff0c;不指定就没有 conda create -n xxx_env python3.8 3. 查看有哪些anacond…...

玩转Docker | 使用Docker搭建Vikunja任务管理应用

玩转Docker | 使用Docker搭建Vikunja任务管理应用 前言一、 Vikunja介绍Vikunja 简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署Vikunja服务下载镜像创建容器检查容器状态检查服务端口安全设置四、访问Vikunja应用注册账号访问Vikunja主页五…...

VMware NSX 4.X Professional V2(2V0-41.24)题库2

What are two supported host switch modes? (Choose two.) A. Overlay Datapath B. Secure Datapath C. Standard Datapath D. Enhanced Datapath E. DPDK Datapath 答案&#xff1a;CD 完整题库见文章底部&#xff01; Which is an advantage of an L2 VPN in an NSX 4.x …...

算法-数据结构-图的构建(邻接矩阵表示)

数据定义 //邻接矩阵表示图 //1.无向图是对称的 //2.有权的把a,到b 对应的位置换成权的值/*** 无向图* A B* A 0 1* B 1 0*/ /*** 有向图* A B* A 0 1* B 0 0*/import java.util.ArrayList; import java.util.List;/*** 带权图* A B* A 0 1* B 0 0*/ p…...

ARCGIS国土超级工具集1.4更新说明

ARCGIS国土超级工具集V1.4版本&#xff0c;功能已增加至54 个。本次更新在V1.3版本的基础上&#xff0c;新增了“拓扑问题修复工具”并同时调整了数据处理工具栏的布局、工具操作界面的选择图层下拉框新增可选择位于图层组内的要素图层功能、数据保存路径新增了可选择数据库内的…...

Ollama+Cherrystudio+beg-m3+Deepseek R1 32b部署本地私人知识库(2025年2月win11版)

之前综合网络各方面信息得到的配置表&#xff1a; 在信息爆炸的时代&#xff0c;数据安全和个性化需求愈发凸显。搭建本地私人知识库&#xff0c;不仅能确保数据的安全性&#xff0c;还能根据个人需求进行个性化定制&#xff0c;实现知识的高效管理和利用。随着技术的不断发展…...

Websocket、WebRTC在大模型中的应用

文章目录 WebSocket简介Websocket流程图使用场景代码示例 WebRTC简介WebRTC&#xff08;Web Real-Time Communication&#xff09;流程图使用场景代码示例 大模型应用&#xff0c;使得 WebSocket&#xff0c; WebRTC 的使用频率越来越高&#xff0c;WebSocket提供了文本输入与大…...

C++ 顺序容器--vector容器详解

元素保存在连续的内存空间中。插入元素或者删除元素通常需要线性时间&#xff0c;当这些操作在尾部执行时&#xff0c;实际运行时间为摊还常量时间。随机访问某个元素的复杂度为常量时间。 1 vector 概述 vector 在<vector>头文件中被定义为一个带有2个类型参数的类模板…...

用Golang与WebAssembly构建高性能Web应用:详解`syscall/js`包

用Golang与WebAssembly构建高性能Web应用&#xff1a;详解syscall/js包 引言为什么选择syscall/js包&#xff1f;适用场景 syscall/js包概述syscall/js包的核心概念1. js.Global2. js.Value3. js.Func4. js.Null 和 js.Undefined syscall/js包在WebAssembly中的位置 环境配置与…...

LeetCode刷题 -- 23. 合并 K 个升序链表

小根堆排序与合并 K 个有序链表的实现 1. 介绍 本技术文档详细介绍了如何使用 小根堆&#xff08;Min Heap&#xff09; 实现 K 个有序链表的合并。 核心思想是&#xff1a; 使用 小根堆 维护当前最小的节点。每次取出堆顶元素&#xff08;最小值&#xff09;加入合并链表&…...