C++(17.5)——list模拟实现扩展

在上篇文章中,实现了list的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。

1. const迭代器:

对于上篇文章中实现的迭代器只能使用于非const类型的对象。对于const类型的遍历,则需要额外编写const类型的迭代器。例如对于下面的场景:

void print_list(const list<int>& s){list<int>::const_iterator it2 = s.begin();while (it2 != s.end()){cout << *it2;it2++;}}

对于const与非const类型的变量的区别,是const类型的对象不能修改。因此,实现const迭代器的第一种方法,便是将非const迭代器的相关代码进行复制然后进行改动,基于const类型本身的性质,只需要将operator*()函数的返回值类型改为const类型即可,对应代码如下:

template<class T>struct __list_const_iterator{typedef ListNode<T> Node;typedef __list_const_iterator<T> self;__list_const_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->_next;return tmp;}const T& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}Node* _node;};

在完成上述步骤后,还需要在list中,引入__list_const_iterator,并且为了方便书写,利用typedef函数将其改写为const_iterator。将成员函数begin(),end()进行复制,然后改为const成员函数,代码如下:

const_iterator begin() const{return _phead->_next;}const_iterator end() const{return _phead;}

 此时,再运行上方给出的代码:

void print_list(const list<int>& s){list<int>::const_iterator it2 = s.begin();while (it2 != s.end()){cout << *it2;it2++;}}
print_list(It);

 运行结果如下:

上述步骤虽然可以实现const迭代器的使用,但是两种迭代器的代码重复率过高。只有二者的成员函数operator*()的返回值类型不同,以及迭代器名称不同。为了简化上述代码,可以使用两个模板参数,即:

template<class T,class Ref>struct __list_iterator{typedef ListNode<T> Node;typedef __list_iterator<T,Ref> self;__list_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->next;return tmp;}Ref& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}Node* _node;};

 其中,第二个模板参数Ref用于表示返回类型是const还是非const。并且,对list中引入的迭代器类型,通过传递不同的参数来进行区分,即:

template<class T>class list{typedef ListNode<T>  Node;public:typedef __list_iterator<T,T&> iterator;typedef __list_iterator<T,const T&> const_iterator;iterator begin(){return _phead->_next;}iterator end(){return _phead;}const_iterator begin() const{return _phead->_next;}const_iterator end() const{return _phead;}Node* _phead;};

2. 代码总览:
 

#include<assert.h>
#include<iostream>
using namespace std;namespace violent
{template<class T>struct ListNode{ListNode(const T& x = T()): _prev(nullptr), _next(nullptr), _data(x){}ListNode<T>* _prev;ListNode<T>* _next;T _data;};template<class T,class Ref>struct __list_iterator{typedef ListNode<T> Node;typedef __list_iterator<T,Ref> self;__list_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->_next;return tmp;}Ref& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}T* operator->(){return &_node->_data;}Node* _node;};/*template<class T>struct __list_const_iterator{typedef ListNode<T> Node;typedef __list_const_iterator<T> self;__list_const_iterator(Node* node): _node(node){}self& operator++(){_node = _node->_next;return *this;}self& operator++(int){self tmp(_node);_node = _node->_next;return tmp;}const T& operator*(){return _node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}Node* _node;};*/template<class T>class list{typedef ListNode<T>  Node;public:typedef __list_iterator<T,T&> iterator;typedef __list_iterator<T,const T&> const_iterator;list(){_phead = new Node;_phead->_next = _phead;_phead->_prev = _phead;}void empty(){_phead = new Node;_phead->_next = _phead;_phead->_prev = _phead;}list(const list<T>& s){empty();for (auto e : s){push_back(e);}}void swap(list<T>& s){std::swap(_phead, s._phead);}list<T>& operator=(list<T> s){swap(s);return *this;}iterator begin(){return _phead->_next;}iterator end(){return _phead;}const_iterator begin() const{return _phead->_next;}const_iterator end() const{return _phead;}/*void push_back(const T& x){Node* newnode = new Node(x);Node* tail = _phead->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _phead;_phead->_prev = newnode;}*/void push_back(const T& x){insert(_phead, x);}void push_front(const T& x){insert(_phead->_next, x);}void insert(iterator pos,const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;}void pop_back(){erase(_phead->_prev);}void pop_front(){erase(_phead->_next);}iterator erase(iterator pos){assert(pos != end());Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return next;}void clear(){iterator i2 = begin();while (i2 != end()){i2 = erase(i2);}}~list(){clear();delete _phead;_phead = nullptr;}Node* _phead;};void print_list(const list<int>& s){list<int>::const_iterator it2 = s.begin();while (it2 != s.end()){cout << *it2;it2++;}}void test1(){list<int> It;It.push_back(1);It.push_back(2);It.push_back(3);It.push_back(4);list<int>::iterator it1 = It.begin();while (it1 != It.end()){cout << *it1 << ' ';++it1;}cout << endl;It.insert(It.begin(), 5);It.insert(It.begin(), 6);It.insert(It.begin(), 7);It.insert(It.begin(), 8);It.push_front(9);It.push_front(9);It.push_front(9);for (auto e : It){cout << e << ' ';}cout << endl;It.pop_back();It.pop_back();It.pop_front();It.pop_front();for (auto e : It){cout << e << ' ';}cout << endl;cout << "const迭代器:";print_list(It);}struct AA{AA(int aa1 = 1, int aa2 = 2): _aa1(aa1), _aa2(aa2){}int _aa1;int _aa2;};void test3(){AA a(2, 3);list<AA> It;It.push_back(a);It.push_back(AA());It.push_back(AA(1, 2));list<AA>::iterator it = It.begin();while (it != It.end()){cout << it->_aa1 << endl;it++;}}
}

#include"list_1.h"int main()
{violent::test3();return 0;
}

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

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

相关文章

【持续更新】2024牛客寒假算法基础集训营1题解 | JorbanS

文章目录 [A - DFS搜索](https://ac.nowcoder.com/acm/contest/67741/A)[B - 关鸡](https://ac.nowcoder.com/acm/contest/67741/B)[C - 按闹分配](https://ac.nowcoder.com/acm/contest/67741/C)[E - 本题又主要考察了贪心](https://ac.nowcoder.com/acm/contest/67741/E)[F -…

Unknown custom element:<xxx>-did you register the component correctly解决方案

如图所示控制台发现了爆红&#xff08;大哭&#xff09;&#xff1a; 报错解释&#xff1a; 当我们看到报错时&#xff0c;我们需要看到一些关键词&#xff0c;比如显眼的“component”和“name”这两个单词&#xff0c; 因此我们就从此处切入&#xff0c;大概与组件有关系。…

Spring Boot--07--@Repository 和@Mapper的区别

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.Repository的作用1.1 含义1.2 Repository与Service和Component有什么区别&#xff1f;1.3 使用场景单独使用Repository&#xff0c;需要配合使用MapperScannerCon…

深度学习的新前沿:突破、应用与挑战

引言 深度学习的快速发展已经在人工智能领域引起了革命性的变化。作为模仿人脑结构和功能的强大工具&#xff0c;深度神经网络在图像识别、自然语言处理、医学诊断等多个领域取得了显著成就。但是&#xff0c;随着技术的不断推进&#xff0c;深度学习也在不断地进化和扩展其能…

云上自动部署丨使用 Terraform 在 AWS 上搭建 DolphinDB

HashiCorp Terraform 是一款基础架构即代码工具&#xff0c;旨在实现 "Write, Plan, and Create Infrastructure as Code"。它通过配置文件来描述云资源的拓扑结构&#xff0c;包括虚拟机、存储账户和网络接口。Terraform 几乎支持市面上所有的云服务&#xff0c;能够…

一键部署FC超级马里奥web游戏

效果展示 安装 拉取镜像 #拉取镜像 docker pull stayhungrystayfoolish666/mario #创建并启动容器 docker run -d -p 10034:8080 --name maliao --restartalways stayhungrystayfoolish666/mario:latest 使用 浏览器打开 http://你的ip:10034/

C++ //练习 4.5 写出下列表达式的求值结果。

C Primer&#xff08;第5版&#xff09; 练习 4.5 练习 4.5 写出下列表达式的求值结果。 ( a ) -30 * 3 21 / 5 ( b ) -30 3 * 21 / 5 ( c ) 30 / 3 * 21 % 5 ( d ) -30 / 3 * 21 % 4 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;…

CSS实现文字大小自适应

遇到的问题&#xff1a; 在写页面的时候&#xff0c;兼容手机和PC页面&#xff0c;这样字体大小就需要根据页面的大小进行动态变化。 解决方法&#xff1a; clamp()函数 clamp() 函数的作用是把一个值限制在一个上限和下限区间&#xff0c;当这个值超过区间范围时&#xff0c;…

YOLO系列助力涨点!新SOTA让缺陷检测更准更快!附开源数据集下载

缺陷检测在工业自动化、质量控制、安全检测等多个实际应用中都有着广泛的需求。因此这个方向是相对容易发表高质量论文的&#xff0c;尤其是当研究涉及到创新的算法、改进的技术、新的应用场景或显著提高检测性能时。 在这其中&#xff0c;YOLO系列算法与缺陷检测的结合已经取…

composer常用命令

查看全局配置信息 composer config -gl 设置镜全局像地址 composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 去掉-g&#xff0c;即表示只有当前项目使用该镜像 批量安装composer项目依赖 composer install 执行该命令后&#xff0c;会读取当…

MySQL中where和having的区别

前言 数据库中的 WHERE 和 HAVING 子句在 SQL 查询中扮演着关键的角色&#xff0c;帮助我们有效地筛选和过滤数据。这两个子句虽然都用于限定结果集&#xff0c;但它们的应用场景和操作对象存在明显的区别。在理解和运用这两个子句的过程中&#xff0c;我们能够更灵活地进行数据…

【C语言】顺序表详解

目录 &#xff08;一&#xff09;顺序表是一种数据结构 &#xff08;二&#xff09;顺序表 &#xff08;1&#xff09;顺序表的必要性 &#xff08;2&#xff09;顺序表的概念及结构 i&#xff0c;线性表 &#xff08;3&#xff09;顺序表的分类 i&#xff0c;顺序表和…

Android SELinux:保护您的移动设备安全的关键

Android SELinux&#xff1a;保护您的移动设备安全的关键 1 引言 移动设备在我们的生活中扮演着越来越重要的角色&#xff0c;我们几乎把所有重要的信息都存储在这些设备上。然而&#xff0c;随着移动应用程序的数量不断增加&#xff0c;安全性也变得越来越关键。这就是为什么…

海洋鱼类检测7种YOLOV8NANO

【免费】海洋鱼类检测&#xff0c;7种类型&#xff0c;YOLOV8训练&#xff0c;转换成ONNX&#xff0c;OPENCV调用资源-CSDN文库 采用YOLOV8NANO训练模型&#xff0c;得到PT模型&#xff0c;然后转换成ONNX&#xff0c;供OPENCV的DNN调用&#xff0c;摆脱PYTORCH依赖&#xff0c…

算法设计与分析实验:最短路径算法

一、网络延迟时间 力扣第743题 本题采用最短路径的思想进行求解 1.1 具体思路 &#xff08;1&#xff09;使用邻接表表示有向图&#xff1a;首先&#xff0c;我们可以使用邻接表来表示有向图。邻接表是一种数据结构&#xff0c;用于表示图中顶点的相邻关系。在这个问题中&am…

轻松打造智能化性能测试监控平台:【JMeter+Grafana+Influxdb】的优化整合方案

在当前激烈的市场竞争中&#xff0c;创新和效率成为企业发展的核心要素之一。在这种背景下&#xff0c;如何保证产品和服务的稳定性、可靠性以及高效性就显得尤为重要。 而在软件开发过程中&#xff0c;性能测试是一项不可或缺的环节&#xff0c;它可以有效的评估一个系统、应…

C语言·贪吃蛇游戏(下)

上节我们将要完成贪吃蛇游戏所需的前置知识都学完了&#xff0c;那么这节我们就开始动手写代码了 1. 程序规划 首先我们应该规划好我们的代码文件&#xff0c;设置3个文件&#xff1a;snack.h 用来声明游戏中实现各种功能的函数&#xff0c;snack.c 用来实现函数&#xff0c;t…

探索Web3.0:下一代互联网的新篇章

随着技术的不断演进和社会的持续发展&#xff0c;我们正逐渐迈入Web3.0时代。Web3.0&#xff0c;作为下一代互联网的代名词&#xff0c;不仅仅是技术的进步&#xff0c;更是一种全新的数字化生态系统&#xff0c;其所带来的影响将深刻地改变着我们的生活、工作和交流方式。 什…

Java二维码图片识别

前言 后端识别二维码图片 代码 引入依赖 <dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.2.1</version></dependency><dependency><groupId>com.google.zxing<…

tuya-open-sdk-for-device使用体验之Windows 下 MSYS2 编译 T2-U 开发板

tuya-open-sdk-for-device 是一款跨芯片平台、操作系统的 IoT 开发框架。它基于通用南向接口设计&#xff0c;支持 Bluetooth、Wi-Fi、Ethernet 等通信协议&#xff0c;提供了物联网开发的核心功能&#xff0c;包括配网&#xff0c;激活&#xff0c;控制&#xff0c;升级等&…