C++ STL中list迭代器的实现

news2025/1/18 3:25:12

list 的模拟实现中,重难点在于迭代器功能的实现,因此本文只围绕 iteratorconst_iterator 的设计进行介绍,其余如增删查改则不再赘述——在C语言的基础上,这些都非常简单。

与 string / vector 不同,list 的节点原生指针不能通过简单的 ++ / * 等实现迭代器,因此我们需要节点指针进行封装利用自定义类型支持运算符重载的性质,完成迭代器的设计。

为了与 STL中list 进行区分,我们在创建的命名空间内实现。

一、iterator 的实现

(双向带头循环)链表及其节点的结构设计:

push_back():

void push_back(const T& x)
{
    Node* newnode = new Node(x);
    Node* tail = _head->prev;

    tail->_next = newnode;
    newnode->_prev = tail;
    _head->_prev = newnode;
    newnode->_next = _head;
}

我们很容易可以插入一组数据,但如果想遍历链表,同时对数据进行修改,则需要实现迭代器。

list 无法像 vector 一样简单地 ++/* 实现节点遍历,且原始指针也不支持对运算符重载,我们需要对 list节点的指针 进行封装

template<class T>
struct __list_iterator
{
    typedef ListNode<T> Node;
    Node* _node;// 被封装的节点指针
    
    // 迭代器的构造
    __list_iterator(Node* node)
			:_node(node)
	{}
};

struct __list_iterator
{
	typedef __list_iterator<T> self;  
    
    self operator++()
    {
        _node = _node->_next;
        return _node;
    }
    
    T& operator*()
    {
        return _node->_data;
    }
};

实际上,编译器优化后,会直接用 _node 对等式左边的变量进行构造。

以此类推,后置++ / 前后置-- / != / == 等都很容易了。

二、const_iterator 及第二个模板参数的引入

const_iterator 不能通过对 iterator 加 const 实现:

const_iterator 是为了防止 list 节点的数据被修改;iterator 加 const 会让迭代器本身无法++/–,导致 const list 无法实现遍历——迭代器不能++/–

const_iterator 本身的功能很简单——防止 list 节点的数据被修改,我们只需要针对性的修改 * 重载,其余与普通迭代器没有区别。

const T& operator*()
{
    return _node->_data;
}
// 普通迭代器 iterator:
// T& operator*() —— 能对节点的数据进行修改

即:

template<class T>
struct __list_const_iterator
{
    // ...
	const T& operator*()
    {
        return _node->_data;
    }
};

template<class T>
class list
{
    // ...
    typedef __list_const_iterator<T> const_iterator;
}

仅有一个函数不同,而其余部分都一样(与 iterator 相比),这种做法不是很好。

因此,我们引入第二个模板参数。

template<class T, class Ref>
struct __list_iterator
{
    // ...
	Ref operator*()
    {
        return _node->_data;
    }
}

template<class T, class Ref>
class list
{
	typedef __list_iterator<T, T&> iterator;
    typedef __list_iterator<T, const T&> const_iterator;
    // ...
}
  • 用一个例子测试 const迭代器:
namespace MyList
{
    void Print(const list<int>& lt)
    {
        for (auto& e : lt)
        {
            cout << e << " ";
        }
        cout << endl;
    }
    void test1()
    {
        list<int> lt;
        lt.push_back(10);
        lt.push_back(20);
        lt.push_back(30);
        lt.push_back(40);
        
        Print(lt);
    }
}

int main()
{
    test1();
    return 0;
}

三、箭头->重载

T* operator->()
{
    return &(_node->_data);
}


观察一下:it->_year ——> it.operator->()_year

此处 it.operator->() 的返回值是 Date* ,不应该写成 it->->_year 吗?

事实上,编译器在此处进行了优化,->-> 的写法反而错了

我们也可以引入第三个模板参数 Ptr ,这就就可以同时实现 T* 和 const T* 。

template<class T, class Ref, class Ptr>
struct __list_iterator
{
    typedef __list_iterator<T, Ref, Ptr> self;
    // ...
};

template<class T>
class list
{
    typedef __list_iterator<T, T&, T*> iterator;
    typedef __list_iterator<T, const T&, const T*> const_iterator;
    // ...
}

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

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

相关文章

27移除元素(简单)-经典面试150题

题目描述 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出…

【高效开发工具系列】Java读取Html

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

计算机考试-软件设计师

文章目录 基础知识分析与设计结构化方法分析与设计基础知识实战法宝 数据库分析与设计基础知识实战法宝 真题练习09下-结构化分析09上-数据库分析 基础知识 分析与设计 整体分析&#xff1a; 1-4分值 15 或者 20 总分55 分 5-6 选做一题 15 总时间150分钟第一题 15分 15分…

【MAC】Multi-Level Monte Carlo Actor-Critic阅读笔记

基本思想&#xff1a; 利用多层次蒙特卡洛方法&#xff08;Multi-Level Monte Carlo&#xff0c;MLMC&#xff09;和Actor-Critic算法&#xff0c;解决平均奖励强化学习中的快速混合问题。 快速混合&#xff1f; 在强化学习中&#xff0c;当我们说一个策略"混合得快"…

绘制太极图 - 使用 PyQt

大家好&#xff01;今天我们将一起来探讨一下如何使用PyQt&#xff0c;这是一个强大的Python库&#xff0c;来绘制一个传统的太极图。这个图案代表着古老的阴阳哲学&#xff0c;而我们的代码将以大白话的方式向你揭示它的奥秘。 PyQt&#xff1a;是什么鬼&#xff1f; 首先&a…

Python爬虫---Scrapy框架---CrawlSpider

CrawlSpider 1. CrawlSpider继承自scrapy.Spider 2. CrawlSpider可以定义规则&#xff0c;再解析html内容的时候&#xff0c;可以根据链接规则提取出指定的链接&#xff0c;然后再向这些链接发送请求&#xff0c;所以&#xff0c;如果有需要跟进链接的需求&#xff0c;意思就是…

hardware simulation——编译框架优化

目录 介绍 修改前的最新代码和框架 学习和修改 最终版本 介绍 -------------------------------------------------------------------------------------------------------------------------- https://www.cnblogs.com/wittxie/p/9836097.html 上次那个虽然能完成基本…

计算方法实验2:利用二分法及不动点迭代求解非线性方程

一、问题描述 利用二分法及不动点迭代求解非线性方程。 二、实验目的 掌握二分法及不动点迭代的算法原理&#xff1b;能分析两种方法的收敛性&#xff1b;能熟练编写代码实现利用二分法及不动点迭代来求解非线性方程。 三、实验内容及要求 二分法 (1) 编写代码计算下列数字…

STM正点mini-新建工程模板,GPIO及寄存器(介绍)

一.新建工程模板(基于固件库) 1.1库函数与寄存器的区别 这里的启动文件都是根据容量来进行区分的 对MDK而言即使include了&#xff0c;也不知道在哪里找头文件 STM32F10X_HD,USE_STDPERIPH_DRIVER 二.新建工程模板(基于寄存器) 上面的大部分配置与固件库的一样 具体可以看手…

linux03 用户权限

01.三种权限 02.UGO&#xff08;root账号&#xff09; 查看权限 不在root文件中写&#xff0c;是因为其他用户不能进来 举个例子 ll是ls -l 第一部分&#xff1a;权限&#xff08;11个字节&#xff09; 第一个&#xff1a;d/- d表示文件夹 - 表示一般文件 二到四&#xff1a…

基于springboot+vue的明星周边产品销售网站(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 研究背景…

初识人工智能,一文读懂机器学习之逻辑回归知识文集(6)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

Java 的文件类的学习总结

目录 一、File 的创建 二、File 类的常用方法 一、File 的创建 二、File 类的常用方法

openssl3.2 - 测试程序的学习

文章目录 openssl3.2 - 测试程序的学习概述笔记openssl3.2 - 测试程序的学习 - 准备openssl测试专用工程的模板openssl3.2 - 测试程序的学习 - test\aborttest.copenssl3.2 - 测试程序的学习 - test\sanitytest.copenssl3.2 - 测试程序的学习 - test\acvp_test.copenssl3.2 - 测…

C++进阶(六)map和set

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、序列式容器与关联式容器二、键值对三、树形结构的关联式容器1、set1、set的介绍2、set的使…

高考复习技巧考研资料、美赛论文及代码,数据收集网站(初高中招生考试全科试卷等)

图&#xff0c;就要从“点、线、面的位置关系”这一内核开始发散&#xff0c;第一层级为彼此的位置关系&#xff0c;平行、相交、异面&#xff08;两直线间位置&#xff09;、垂直&#xff08;相交或异面中的特殊位置&#xff09;&#xff0c;多面体、旋转体等&#xff0c;然后…

2024-macOS系统或Kail系统重——破解ZIP压缩的文件密码

2024-macOS系统或Kail系统重——破解ZIP压缩的文件密码 1. 你们有遇见这样子的情况么&#xff1a; 别人给你发的zip或者下载的zip文件&#xff0c;没有密码打不开么网上都是win系统的&#xff0c;都是没有macOS系统的&#xff0c;所以比较烦恼 2. 所以我就想到了代码&#x…

GoogLeNet模型详解

模型介绍 GoogLeNet是谷歌工程师设计的深度神经网络结构&#xff0c;于2014年在ImageNet比赛中取得了冠军。它的设计特点在于既有深度&#xff0c;又在横向上拥有“宽度”&#xff0c;并采用了一种名为Inception的核心子网络结构。这个网络名字中的“GoogLeNet”是对LeNet的致…

AtCoder Beginner Contest 338D - Island Tour【枚举】

原题链接&#xff1a;https://atcoder.jp/contests/abc338/tasks/abc338_d Time Limit: 2 sec / Memory Limit: 1024 MB Score: 425 points 问题陈述 AtCoder 群岛由 N 座岛屿组成&#xff0c;这些岛屿由 N 座桥梁连接。这些岛屿的编号从1到N&#xff0c;i(1≤i≤N−1)桥双…

Stable Diffusion系列(四):提示词规则与使用

文章目录 基础规则高级规则插件使用 基础规则 所谓提示词&#xff0c;也就是文生图中的文&#xff0c;由连贯的英语单词或句子组成。其最基础的规则是&#xff1a; 不同提示词之间需要用英文逗号分隔&#xff0c;空格和换行不影响读取想混合多个要素时使用|&#xff0c;相当于…