C++初阶 | 反向迭代器(补充)

本文详细介绍了如何在C++中使用适配器复用Iterator实现vector和list的反向迭代器,包括基本成员函数的编写,以及如何处理vector和list的rbegin和rend操作。
摘要由CSDN通过智能技术生成

摘要:vector 和 list 反向迭代器实现 

前言:Iterator 的意义在于封装屏蔽底层,实现的复杂细节用统一简单的方式访问容器。其底层可能是原生指针,也可能不是。例如 vector 模拟实现中 iterator 的底层实现就是一个指针,而 list 的模拟实现中的 iterator 是一个自定义类型。 

// 将以下代码适配到vector和list中做反向迭代器,理解反向迭代器的原理
namespace Btl
{
	// 适配器 -- 复用
	template<class Iterator, class Ref, class Ptr>
	struct Reverse_iterator
	{
		Iterator _it;
	};
    // vector和list反向迭代器实现
}

整体架构的思路:复用 Iterator 来封装 Reverse_Iterator 


1. Reverse_Iterator 基本成员函数

反向迭代器需要实现的基本成员函数同普通迭代器一样,而实现思路也大差不差。只是要注意,反向迭代器的成员变量就是一个 iterator,因此函数实现即复用 iterator 的成员函数即可。

个别成员函数提醒:
operator->() 这个函数本质上就是对 operator*() 的结果取地址,所以这里可以复用 operator*() 写成 &(operator*()),也可以选择复用 Iterator 的operator->() 函数写成 it.operator->()

namespace Btl
{
	// 适配器 -- 复用
	template<class Iterator, class Ref, class Ptr>
	struct Reverse_iterator
	{
		typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
		Iterator _it;
		

		Ref operator*()
		{
			return *it;
		}

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

		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		Self operator++(int)
		{
			Self tmp = _it;
			--_it;
			return tmp;
		}

		Self operator--(int)
		{
			Self tmp = _it;
			++_it;
			return tmp;
		}

		bool operator!=(const Self& s)
		{
			return _it != s._it;
		}

		bool operator==(const Self& s)
		{
			return _it == s._it;
		}
	};
}

2. list 的 Reverse_Iterator 

(list 的成员变量和其他成员函数在此处省略不展示,该部分具体内容请参考 “ list 的模拟实现 ”一文,此处仅展示其迭代器的实现) 

从上图中不难看出 rbegin = --end ,rend = --begin (rend = end 这样写也可以).(ps.这不是正确的写法,只是表达这样的意思)

namespace Btl
{
	// List的节点类
	template<class T>
	struct ListNode
	{
		ListNode(const T& val = T())
			: _val(val)
			, _pPre(nullptr)
			, _pNext(nullptr)
		{}

		ListNode<T>* _pPre;
		ListNode<T>* _pNext;
		T _val;
	};


	//List的迭代器类
	template<class T, class Ref, class Ptr>
	class ListIterator
	{
		typedef ListNode<T>* PNode;
		typedef ListIterator<T, Ref, Ptr> Self;
	public:
		//constructor
		ListIterator(PNode pNode = nullptr)
			:_pNode(pNode)
		{}
		ListIterator(const Self& l)//copy constructor
		{
			_pNode = l._pNode;
		}

		//operations
		Ref operator*()
		{
			return _pNode->_val;
		}
		Ptr operator->()
		{
			return &_pNode->_val;
		}
		Self& operator++()
		{
			_pNode = _pNode->_pNext;
			return *this;
		}
		Self operator++(int)
		{
			Self tmp = _pNode;
			_pNode = _pNode->_pNext;
			return tmp;
		}
		Self& operator--()
		{
			_pNode = _pNode->_pPre;
			return *this;
		}
		Self operator--(int)
		{
			Self tmp = _pNode;
			_pNode = _pNode->_pPre;
			return tmp;
		}
		bool operator!=(const Self& l)
		{
			return _pNode != l._pNode;
		}
		bool operator==(const Self& l)
		{
			return _pNode == l._pNode;
		}
		PNode _pNode;
	};




	//list类
	template<class T>
	class list
	{
		typedef ListNode<T> Node;
		typedef Node* PNode;
	public:
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&, const T&> const_iterator;

		typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_iterator<const_iterator, T&, T*> const_reverse_iterator;

		///
		// List Iterator
		iterator begin()
		{
			return _pHead->_pNext;
		}
		iterator end()
		{
			return _pHead;
		}
		const_iterator begin() const
		{
			return _pHead->_pNext;
		}
		const_iterator end()const
		{
			return _pHead;
		}

		reverse_iterator rbegin()
		{
			return (--end());
		}

		reverse_iterator rend()
		{
			return (--begin());
		}

		const_reverse_iterator rbegin()const
		{
			return (--end());
		}

		const_reverse_iterator rend()const
		{
			return (--begin());
		}

        //………………………………
		
	};
}

3. vector 的 Reverse_Iterator 

反向迭代器的实现同 list 。

报错:返回临时对象

自定义对象const变量调用非const函数的典型例子:匿名对象(具有常性)调用非const成员函数,当我们只是想用调用某个自定义类的成员函数而不想为此特意创建自定义对象时,我们常常通过匿名对象来调用其成员函数。

对于上图所描述的报错,可以通过将 --end() 改成 end()-1下面展示一种更优的处理办法。


4. 完善 Reverse_Iterator

思路:

注意:这里处理 --(减减) 操作必须通过一个临时变量来执行,该操作不能直接作用在 reverse_iterator 的成员变量 it 上!不然每次对反向迭代器解引用一次还会附带一次 -- 操作!

完整的迭代器实现:(ps.只展示和反向迭代器直接相关的,其他部分省略。另外,注意只要是自己实现了构造函数,一定要有默认构造,否则可能会出现问题)

namespace Btl
{
	// 适配器 -- 复用
	template<class Iterator, class Ref, class Ptr>
	struct Reverse_iterator
	{
		typedef Reverse_iterator<Iterator, Ref, Ptr> Self;
		Iterator _it;

		Reverse_iterator()//默认构造函数
		{}

		Reverse_iterator(Iterator it)
			:_it(it)
		{}

		Ref operator*()
		{
			Iterator tmp = _it;
			return *(--tmp);
		}

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

		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		Self operator++(int)
		{
			Self tmp = _it;
			--_it;
			return tmp;
		}
		Self operator--(int)
		{
			Self tmp = _it;
			++_it;
			return tmp;
		}

		bool operator!=(const Self& s)
		{
			return _it != s._it;
		}

		bool operator==(const Self& s)
		{
			return _it == s._it;
		}
	};

}

namespace Btl
{
	template<class T>
	class vector
	{
	public:

		// Vector的迭代器是一个原生指针

		typedef T* iterator;
		typedef const T* const_iterator;

		typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_iterator<const_iterator, T&, T*> const_reverse_iterator;


		iterator begin()
		{
			return _start;
		}

		iterator end()
		{
			return _finish;
		}


		const_iterator cbegin()const
		{
			return _start;
		}

		const_iterator cend()const
		{
			return _finish;
		}

		reverse_iterator rbegin()
		{
			return end();
		}

		reverse_iterator rend()
		{
			return begin();
		}

		const_reverse_iterator rbegin()const
		{
			return cend();
		}

		const_reverse_iterator rend()const
		{
			return cbegin();
		}
        //…………………………………………………………

	};
}

namespace Btl
{
	//list类
	template<class T>
	class list
	{
	public:
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&, const T&> const_iterator;

		typedef Reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef Reverse_iterator<const_iterator, T&, T*> const_reverse_iterator;


		///
		// List Iterator
		iterator begin()
		{
			return _pHead->_pNext;
		}
		iterator end()
		{
			return _pHead;
		}
		const_iterator begin() const
		{
			return _pHead->_pNext;
		}
		const_iterator end()const
		{
			return _pHead;
		}

		reverse_iterator rbegin()
		{
			return end();
		}

		reverse_iterator rend()
		{
			return begin();
		}

		const_reverse_iterator rbegin()const
		{
			return end();
		}

		const_reverse_iterator rend()const
		{
			return begin();
		}

        //…………………………………………………………………………

	};
}

END

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

畋坪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值