stl中的list模拟实现

目录

  • 一、list的简单介绍
  • 二、写出节点的代码
  • 三、模拟实现迭代器(重点)
    • 1、list中的迭代器是怎么实现的
    • 2、编写iterator类的代码
    • 3、对const_iterator进行理解
    • 4、编写const_iterator类的代码
    • 5、对iterator类和const_iterator类进行合并
  • 四、list类进行代码实现

一、list的简单介绍

首先我们要清楚list是一个带头双向循环的链表。

二、写出节点的代码

在下面代码中我们用到了模板,并且用的是struct没有用class,这是因为我们使用struct时相当于这一个类是公开的,当然我们也可以使用class但是得使用友元函数比较麻烦。

	template<class T>//这里用到了模板struct listnode{T _data;listnode* _next;listnode* _prev;listnode(const T& x = T())//这里使用的是匿名函数,因为不确定x是什么类型,所以给了一个匿名函数的全缺省:_data(x), _next(nullptr), _prev(nullptr){}};

三、模拟实现迭代器(重点)

1、list中的迭代器是怎么实现的

我们可以查看stl的源码进行查看,如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看出list的迭代器就是由链表的一个节点指针来进行控制的,然后再进行对符号的重载

2、编写iterator类的代码

根据上述可编写以下代码:

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

3、对const_iterator进行理解

首先我们要清楚是对谁加const,是对迭代器本身加const还是对迭代器指向的内容加const,我们平常使用const_iteratot时我们可以对迭代器进行++或–,但是不可以对迭代器指向的内容进行修改,由此可以看出我们的const_iterator和iterator是两个类不可以直接对iterator加const

4、编写const_iterator类的代码

template<class T>struct list_const_iterator{typedef listnode<T> Node;typedef list_const_iterator<T> self;Node* _node;list_iterator(Node* node) {_node = node;}self& operator++() {_node = _node->_next;return *this;}self& operator--() {_node = _node->_prev;return *this;}self operator++(int) {self temp(*this);_node = _node->_next;return temp;}self operator--(int) {self temp(*this);_node = _node->_prev;return temp;}const T* operator->() {return &_node->_data;}const T& operator*() {return _node->_data;}bool operator!=(const self& s) {return s._node != _node;}bool operator==(const self& s) {return s._node == _node;}};

5、对iterator类和const_iterator类进行合并

在编写iterator类和const_iterator类我们发现除了下面的代码不一样其余的代码都是一样的。
在这里插入图片描述
在这里插入图片描述
但是这样写的话,代码就会冗余,所以这时我们用一个类模板,对代码进行修改,如下:

template<class T,class Ref,class Ptr>struct list_iterator{typedef listnode<T> Node;typedef list_iterator<T,Ref,Ptr> self;Node* _node;list_iterator(Node* node) {_node = node;}self& operator++() {_node = _node->_next;return *this;}self& operator--() {_node = _node->_prev;return *this;}self operator++(int) {self temp(*this);_node = _node->_next;return temp;}self operator--(int) {self temp(*this);_node = _node->_prev;return temp;}Ptr operator->() {return &_node->_data;}Ref operator*() {return _node->_data;}bool operator!=(const self& s) {return s._node != _node;}bool operator==(const self& s) {return s._node == _node;}};

四、list类进行代码实现

这里主要是写构造函数、拷贝构造、赋值拷贝、析构函数、迭代器的begin()和end()的实现,以及其他功能的实现。
代码如下:

template<class T>class list {typedef listnode<T> Node;public:typedef list_iterator<T,T&,T*> iterator;typedef list_iterator<T,const T&,const T*> const_iterator;void empty_init() {_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}iterator begin() {return _head->_next;}iterator end() {//返回的是最后一个节点的后一个,所以返回的是头节点return _head;}list() {empty_init();}list(list<T>& it) {empty_init();for (auto e : it) {push_back(e);}}void swap(list<T>& It) {std::swap(_head, It->_head);std::swap(_size, It->_size);}list<T>& operator=(list<T>& It){swap(It);return *this;}~list(){clear();delete(_head);_size = 0;}void push_back(const T& x) {insert(end(), x);}void push_front(const T& x) {insert(begin(), x);}void pop_front() {erase(begin());}void pop_back() {erase(--end());}void clear() {while (!empty()) {pop_back();}}bool empty() {return _size == 0;}size_t size() {return _size;}iterator erase(iterator pos) {Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;--_size;return iterator(next);}iterator insert(iterator pos, T x) {Node* cur = pos._node;Node* newNode = new Node(x);Node* prev = cur->_prev;prev->_next = newNode;newNode->_prev = prev;newNode->_next = cur;cur->_prev = newNode;++_size;return iterator(newNode);}private:Node* _head;size_t _size;};

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

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

相关文章

国产六核CPU商显板,三屏异显,米尔基于全志D9360开发板

芯驰D9-Pro 自主可控、安全可信的高性能商显方案 采用国产CPU&#xff1a;集成了6个ARM Cortex-A551.6GHz 高性能CPU和1个ARM Cortex-R5800MHz&#xff1b; 高性能的高安全HSM安全的处理器&#xff0c;支持TRNG、AES、RSA、SHA、SM2/3/4/9&#xff1b; 它包含100GFLOPS 3D G…

软件测试|Beautiful Soup库详细使用指南

简介 Beautiful Soup是一款强大的Python库&#xff0c;广泛用于解析HTML和XML文档&#xff0c;从中提取数据并进行处理。它的灵活性和易用性使得数据抽取变得简单&#xff0c;本文将详细介绍Beautiful Soup库的基本用法和示例。 安装Beautiful Soup 首先&#xff0c;需要确保…

Flink CDC 实时抽取 Oracle 数据-排错调优

前言 Flink CDC 于 2021 年 11 月 15 日发布了最新版本 2.1&#xff0c;该版本通过引入内置 Debezium 组件&#xff0c;增加了对 Oracle 的支持。对该版本进行试用并成功实现了对 Oracle 的实时数据捕获以及性能调优&#xff0c;现将试用过程中的一些关键细节进行分享。 使用…

超简单的简历模板精选5篇

HR浏览一份简历也就25秒左右&#xff0c;如果你连「好简历」都没有&#xff0c;怎么能找到好工作呢&#xff1f; 如果你不懂得如何在简历上展示自己&#xff0c;或者觉得怎么改简历都不出彩&#xff0c;那请你一定仔细读完。 个人求职简历第 1 篇 男 22 本科 AI简历 市场营…

44-js return返回值,全局作用域,局部作用域,隐式作用域,变量的生命周期,delete释放内存

1.return返回值:函数执行后剩下结果就是返回值。 function fn(a,b,c){//return返回值return(a+b+c);// console.log("aaa"); //return之后的值都不在执行了// alert("bbb"); //return之后的值不在执行了}console.log(fn(1,2,3)*10); 2.作用…

【c++】类和对象1

1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完 成 …

计算机体系结构动态调度(计分板及Tomasulo)学习记录

1.动态调度核心思想&#xff1a;允许就绪指令越过前方停顿指令&#xff0c;提前进入运行&#xff08;乱序执行&#xff09; 就绪指令指不存在资源冲突、操作数已就绪的指令&#xff0c;例如&#xff0c;计分板算法使用计分板来实现&#xff0c;Tomasulo使用保留站来实现&#…

2024Flutter岗位面试题总结

StatelessWidget和StatefulWidget的区别是什么&#xff1f; StatelessWidget是一个不可变的类&#xff0c;充当UI布局中某些部分的蓝图&#xff0c;当某个组件在显示期间不需要改变&#xff0c;或者说没有状态&#xff08;State&#xff09;&#xff0c;你可以使用它。 Statef…

2024年MIA最新生成综述:基于深度学习的MRI/CT/PET合成【文献阅读】

2024年MIA最新生成综述&#xff1a;基于深度学习的MRI/CT/PET合成【文献阅读】 基本信息 标题&#xff1a;Deep learning based synthesis of MRI, CT and PET: Review and analysis发表年份: 2024期刊/会议: Medical Image Analysis分区&#xff1a; SCI 1区IF&#xff1a;1…

泛型进阶: 泛型方法 通配符

泛型方法 定义语法 方法限定符 <类型参数列表> 返回值类型 方法名称(形参列表) {...} 示例 public class Test {//静态的泛型方法 需要在static后用<>声明泛型参数public static <E> void swap(E[] array, int i, int j) {E t array[i];array[i] array[j…

【已解决】RAR压缩文件可以转换为ZIP格式吗?

想把RAR压缩文件转换成ZIP格式文件&#xff0c;除了可以把RAR压缩包解压后&#xff0c;再重新压缩成ZIP格式&#xff0c;还可以利用WinRAR解压缩软件的“格式转换功能”来实现。不清楚的小伙伴&#xff0c;一起来看看如何操作吧。 首先&#xff0c;通过WinRAR解压缩软件打开RA…

【软件测试】路径覆盖

题目要求&#xff1a; a) 流程图如下&#xff1a; b) Consider test cases ti (n 3) and t2 ( n 5). Although these tour the same prime paths in printPrime(), they dont necessarily find the same faults. Design a simple fault that t2 would be more lik…