【C++】STL中 list 反向迭代器的模拟实现

在上篇文章实现了 list 后,我们实现了其对应的迭代器,但是对于 list,还有一个反向迭代器我们呢没有实现,但是反向迭代器不仅仅可以在 list 中使用,在 vector 中我们进行适配,同样也可以使用,所以我们这篇博客我们实现的反向迭代器是实现迭代器适配器的作用的。

我们反向迭代器的思路是复用正向迭代器的功能,使用一个正向迭代器来创建一个反向迭代器,如果是vector的正向迭代器创建的就是vector的反向迭代器,如果是 list 的正向迭代器,那创建的就是 list 的反向迭代器。

目录

一、反向迭代器定义

二、反向迭代器的功能

2.1 operator++

2.2 operator--

2.3 operator*

2.4 operator->

2.5 operator!=

三、list+iterator+resever_iterator


一、反向迭代器定义

同样,我们之前实现普通迭代器是声明了一个迭代器类。此时,我们也要定义一个反向迭代器类。

而这个反向迭代器是由正向迭代器构造而来的。

template 
	class _resever_iterator_list
	{
		Iterator _cur;
	  
		typedef __reverse_Iterator RIterator;
    }

 //根据一个正向迭代器创建我们的反向迭代器
	__reverse_Iterator(Iterator it)
		:_cur(it)
	{}

在list类中,我们要重命名一下反向迭代器,并将其调用接口写好。

其中关于模板参数的书写,我们要注意一下。

第一个模板参数是普通迭代器类型。

第二个是迭代器其指向其数据的数据类型的引用。

第三个是迭代器其指向其数据的数据类型的指针。

并在此基础上定义好const_Riterator.

//正向迭代器
typedef __list_iterator  iterator;
typedef __list_iterator const_iterator;

//反向迭代器
typedef __reverse_Iterator reverse_iterator;
typedef __reverse_Iterator const_reverse_iterator;

这样的好处是,调用普通的 rbegin() 则创建普通的反向迭代器,其中 operator* 的返回值是可修改的,operator-> 的返回值也是可修改的指针。

而 const 成员调用的是 const 型rbegin(),则创建了const_Riterator。

以下是 list 中通过普通迭代器构造出反向迭代器的 rbegin()、rend()。

//使用 end() 构造反向迭代器的 rbegin()
Riterator rbegin()
{
	return Riterator(end());
}
const_Riterator rbegin() const
{
	return const_Riterator(end());
}
Riterator rend()
{
	return Riterator(begin());
}
const_Riterator rend() const
{
	return const_Riterator(begin());
}

二、反向迭代器的功能

因为反向迭代器是使用正向迭代器构造的,所以反向迭代器的功能都是建立在正向迭代器一系列运算符重载已经实现的基础上完成的。

2.1 operator++

//反向迭代器的++ 相当于 正向迭代器的--
Riterator operator ++()
{
	_cur--;
	return *this;
}
Riterator operator ++(int)
{
	Riterator temp(_cur);
	_cur--;
	return temp;
}

2.2 operator--

Riterator operator --()
{
	_cur++;
	return *this;
}
Riterator operator--(int)
{
	Riterator temp(_cur);
	_cur++;
	return temp;
}

2.3 operator*

这里先明确一点 STL 中,反向迭代器的rbegin()是由 list 的 end() 构造的,也就是_head节点。所以我们在解引用的时候,其实是返回其前一个位置的数据。这样做的好处是为了做到迭代器指向的对称。

Ref operator*()
{
	//rebegin 是由 end 构造的,所以*是要返回_cur的上一个位置
	auto temp = _cur;
	--temp;
	return *temp;
}

2.4 operator->

Ptr operator->()
{
	//返回上一个位置的 解引用
	return &(operator*());
}

2.5 operator!=

//注意 要使用const 引用 因为存在 it 是临时变量的可能
bool operator!=(const Riterator& it)
{
	return _cur != it._cur;
}

三、list+iterator+resever_iterator

namespace Brant
{
	template 
	class _list_node
	{
	public:
		//因为prev指向的是节点,所以要使用_list_node*
		_list_node* _prev;
		_list_node* _next;
		T _data;

		//创建节点时,进行初始化
		_list_node(const T& x = T())
			:_data(x)
			,_next(nullptr)
			,_prev(nullptr)
		{}
	};

    //list的迭代器,就是一个模仿指针的类
	template 
	class __iterator_list
	{
	public:
		typedef _list_node Node;
		typedef __iterator_list iterator;
		Node* _node;

		//要先传来一个list节点  ,才能创建一个迭代器
		__iterator_list(Node* node)
			:_node(node)
		{}

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

		//注意,end() 传入的是临时变量,所以要使用const 传参
		bool operator!=(const iterator& it)
		{
			return _node != it._node;
		}

		iterator& operator++()
		{
			_node = _node->_next;
			//node是list_node    *this才是迭代器
			return *this;
		}

		iterator operator++(int)
		{
			//要先创建一个 迭代器
			iterator temp(_node);
			_node = _node->_next;
			return temp;
		}

		iterator operator--()
		{
			_node = _node->_prev;
			return *this;
		}
		iterator operator--(int)
		{
			iterator temp(_node);
			_node = _node->_prev;
			return temp;
		}
        
		//往list中存放 自定义类型就很需要->操作符
		//如果data中存放的是自定义类型
		//即很容易访问到 自定义类型中的数据。
		T& operator->()
		{
			return &(operator*());
		}
	};

	//复用,迭代器适配器
	template 
	class _resever_iterator_list
	{
	public:
		iterator _cur;
		typedef _resever_iterator_list Riterator;

		//使用一个正向迭代器构造一个反向迭代器
		_resever_iterator_list(iterator it)
			:_cur(it)
		{}

		//反向迭代器的++ 相当于 正向迭代器的--
		Riterator operator ++()
		{
			_cur--;
			return *this;
		}
		Riterator operator ++(int)
		{
			Riterator temp(_cur);
			_cur--;
			return temp;
		}
		Riterator operator --()
		{
			_cur++;
			return *this;
		}
		Riterator operator--(int)
		{
			Riterator temp(_cur);
			_cur++;
			return temp;
		}

		Ref operator*()
		{
			//rebegin 是由 end 构造的,所以*是要返回_cur的上一个位置
			auto temp = _cur;
			--temp;
			return *temp;
		}

		Ptr operator->()
		{
			//两种都可以
			//return _cur.operator->();
			//return &(*_cur;);

			//返回上一个位置的 解引用
			return &(operator*());
		}

	/*	bool operator !=(const Riterator& it)
		{
			return _cur!=it->_cur;
		}*/
        // .操作符是直接进行使用的 .操作符是无法重载的
		bool operator!=(const Riterator& it)
		{
			return _cur != it._cur;
		}
	};

	template 
	class list
	{
	public:
		//注意 typedef ,第一个参数是正向迭代器,第二个 数据类型data的引用,第三个data的指针
		typedef _list_node Node;

		typedef __iterator_list iterator;
		typedef __iterator_list const_iterator;
		
		typedef _resever_iterator_list Riterator;
		typedef _resever_iterator_list const_Riterator;
		//直接使用this指针进行构造
		void empty_Init()
		{
			_head= new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}
		//实现一个无参的构造
		list()
		{
			empty_Init();
		}
		//一个带参的构造
		//template 
		//list(InputIterator first, InputIterator last)
		//{

		//}
		拷贝构造  st2(st1);
		//list(const list& lt)
		//{
		//	empty_Init();
		//	std::swap()
		//}

		//插入数据
		void push_back(const T& x)
		{
			//prev  tail  newnode
			Node* newnode = new Node(x);
			Node* tail = _head->_prev;
			newnode->_next = _head;
			newnode->_prev = tail;
			tail->_next = newnode;
			_head->_prev = newnode;
		}
		
		iterator begin()
		{
			return iterator(_head->_next);
		}
		const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}
		iterator end()
		{
			return iterator(_head);
		}
		const_iterator end() const
		{
			return const_iterator(_head);
		}


		Riterator rbegin()
		{
			return Riterator(end());
		}
		const_Riterator rbegin() const
		{
			return const_Riterator(end());
		}
		Riterator rend()
		{
			return Riterator(begin());
		}
		const_Riterator rend() const
		{
			return const_Riterator(begin());
		}

	private:
		Node* _head;
	};
}

你可能感兴趣的:(C++,c++,开发语言)