C++:浅谈双向迭代器--以list迭代器为例

前言

这篇文章实际上我感觉还是没有讲清楚,有问题的话,还请读者在评论区指出。

迭代器主要是分为随机迭代器和双向迭代器。

随机迭代器由于在物理空间上是连续的,所以支持++,--,+,-,>,<,+=,-=等操作。

双向迭代器在物理空间上不连续,不能够支持+,-,>,<,等操作,但支持++,--。

这篇文章主要讲解双向迭代器如何在物理空间不连续的情况下实现迭代器的通用功能。

本文以list容器为例。

这篇文章实际上我感觉还是没有讲清楚,有问题的话,还请读者在评论区指出。

正文

我们知道list容器的每一个节点都是有三个元素,prev和next指针以及数据data。

这三个元素封装到Node类里面,作为list的节点。

首先,假设我们已经有了auto it = begin()迭代器,我们想要访问下一个元素怎么办,很显然,需要it = it->next,才能访问下一个元素。

那么矛盾来了,迭代器毕竟不是指针啊,不能这么使用,迭代器肯定是使用++it来访问下一个元素,诶,怎么解决这个问题呢?

是不是可以想到运算符重载来改变对象的行为。

但是,还是存在一些问题的,如果在list类里面去重载这些迭代器所需要的运算符,当其他的函数需要使用这些运算符本身时,那不就又出现矛盾了嘛。

怎么解决呢?

当...当...当...
我们可以考虑使用**封装的设计模式,将list的原生指针和这些需要重载的运算符重载到一个类里面**,这样就可以独立使用,而且不会干扰list的其他函数。

模拟实现中遇到的困难和解决办法

a、要时刻清楚每一个类是干嘛的,list里面类是比较多的,很容以把自己绕糊涂

b、要学会代码复用,比如写完了insert,那push_back直接调用insert函数就行

c、一处比较有意思的设计技巧
在设计iterator和const_iterator的时候,怎样快速的实现两个类呢?要不要傻乎乎的把类似的代码写两遍呢?
哎呀,我们是学过模版的嘛,重复的工作丢给编译器去实现就好啦。
template<class T,class Ref,class Ptr>
我们给迭代器类里面放三个模版参数,iterator实例化的时候就传T&和T就可以了,const_iterator实例化的时候传const T&和const T ,编译器就会帮我们实现这两个类。
如果只传一个模版参数的话,那就得傻乎乎的写两个类了。

ps:实际上传三个模版参数也是实现两个类,只是编译器帮我们把重复的工作实现了而已。

代码

C++ 复制代码
template<class T,class Ref,class Ptr>
struct ListIterator
{
	typedef ListNode<T> Node;
	typedef ListIterator<T, Ref, Ptr> Self;

	Node* _node;

	ListIterator(Node* node):_node(node) {}

	Self& operator++()
	{
		_node = _node->_next;
		return *this;
	}

	Self operator++(int)
	{
		Self ret(_node);
		_node = _node->_next;

		return ret;
	}

	Self& operator--()
	{
		_node = _node->_prev;
		return *this;
	}

	Self operator--(int)
	{
		Self ret(_node);
		_node = _node->_prev;
		return ret;
	}

	Ref operator*()//解引用
	{
		return _node->_data;
	}

	Ptr operator->()//成员访问操作符的重载
	{
		return &(_node->_data);
	}
	
	bool operator!=(const Self& it)
	{
		return _node != it._node;
	}

	bool operator==(const Self& it)
	{
		return _node == it._node;
	}
};
相关推荐
阿珊和她的猫1 小时前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
fouryears_234174 小时前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
我好喜欢你~4 小时前
C#---StopWatch类
开发语言·c#
lifallen6 小时前
Java Stream sort算子实现:SortedOps
java·开发语言
IT毕设实战小研6 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
快乐的划水a6 小时前
组合模式及优化
c++·设计模式·组合模式
cui__OaO7 小时前
Linux软件编程--线程
linux·开发语言·线程·互斥锁·死锁·信号量·嵌入式学习
星星火柴9367 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
鱼鱼说测试7 小时前
Jenkins+Python自动化持续集成详细教程
开发语言·servlet·php
艾莉丝努力练剑8 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法