List迭代器的模拟实现

List迭代器

迭代器就是像指针一样的东西,通过迭代器可以对容器进行访问,迭代器屏蔽了容器的底层实现细节。

在STL中list迭代器是一个双向带头循环的链表,因为底层结构是链表空间是不连续的,所有我们不能直接对节点的指针++,来得到下个节点的地址。这时我们就需要自定义一个类型,该类型可以实现迭代器的操作。

template<class T>
class __List_iterator
{
public:
	node* _node;
};

类的成员变量是一个节点的指针。

需要在类中对迭代器++或者–的操作,++就是说我们需要得到下个节点的迭代器,在这里呢,迭代器就是封装的节点的指针,所以++和–也就是对节点的指针进行操作,来得到前后个节点的指针。

template<class T>
class __List_iterator
{
public:
	node* _node;
	typedef ListNode<T> node;
	typedef __List_iterator<T> self;
public:
	self& operator++()
	{
		_node = _node->next;
		return *this;
	}

	self& operator--()
	{
		_node = _node->prev;
		return *this;
	}
};

当实现了迭代的++和–后,就可以通过迭代器进行加减啦,如果我们需要遍历容器此时还需要实现一个!=;也就是两个节点指针进行比较。

		bool operator!=(const self& it)const
		{
			return _node != it._node;
		}

接下来实现*和->,通过*我们可以取出节点的数据,->返回的是当前节点数据的地址。

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

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

到这里我们完成了迭代器的基本功能,那么现在就会有一个新的问题,如果现在是一个const类型对象,此时就需要调用const迭代器,const迭代器是不允许对数据进行修改的,在上面的代码中如果使用的是const对象调用*和->,都可以完成对数据的修改,这是不对的。

  • 现在有一种方案就是在创建一个类,这个类实现的const迭代器,这样写的话就会使代码存在大量的冗余。
  • 另一种方法就是在迭代器的模板中在添加两个模板参数,用来确定*和->返回的类型。
	template<class T, class Ref, class Ptr>
	class __List_iterator
	{
	public:
		typedef ListNode<T> node;
		typedef __List_iterator<T, Ref, Ptr> self;
	public:
		__List_iterator(node* x)
			:_node(x)
		{}

		bool operator!=(const self& it)const
		{
			return _node != it._node;
		}
		self& operator++()
		{
			_node = _node->next;
			return *this;
		}

		self& operator--()
		{
			_node = _node->prev;
			return *this;
		}
        
		Ref operator*()
		{
			return _node->val;
		}

		Ptr operator->()
		{
			return &_node->val;
		}
		node* _node;
	};

如果是一个const迭代器,那么Ref就是const T&,Ptr就是const T*,此时我们就可以通过一个类,来实现不同的迭代器返回不同类型的结果。
在这里插入图片描述

反向迭代器

反向迭代器我们直接复用正向迭代器就可以

template<class iterator, class Ref, class Ptr>
	class __Reverse_iterator
	{
	public:
		typedef __Reverse_iterator<iterator, Ref, Ptr> reverse_iterator;
	public:

		__Reverse_iterator(const iterator& it)
			:_rit(it)
		{}

		Ref operator*()
		{
			iterator tmp = _rit;
			return *--tmp;
		}

		Ptr operator->()
		{
			return &operator*();
		}

		reverse_iterator& operator++()
		{
			--_rit;
			return *this;
		}
		reverse_iterator& operator--()
		{
			++_rit;
			return *this;
		}

		bool operator!=(const reverse_iterator& it)const
		{
			return  _rit != it._rit;
		}
	private:
		iterator _rit;
	};

我们让正向迭代器的begin做反向迭代器的end,正向的end做反向的begin
在这里插入图片描述

反向迭代器的++复用的就是正向的–,反向的–复用的是正向的++;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值