[C++] Implementação de simulação do iterador reverso

Prefácio:

     Nos artigos anteriores, ao simular a implementação de string, vetor e lista, apenas simulamos a implementação do iterador, e não implementamos o iterador reverso separadamente.Na verdade, o autor deixou um pouco de reflexão aqui.

Índice

(1) Maneira tradicional de escrever o iterador reverso

(2) Implementação de simulação do iterador reverso (modo adaptador)


(1) Maneira tradicional de escrever o iterador reverso

    Com base em nossa implementação simulada de iteradores diretos, a implementação de iteradores reversos não é realmente difícil para todos. Nada mais é do que o rbegin no iterador reverso é o meio-termo avançado, rend é start, a operação ++ é avançar um espaço, -- é retroceder e assim por diante.

    Vamos rasgar um iterador reverso da lista do pensamento inerente de todos:

template<class T, class Ref, class Ptr>
	struct __list_reverse_iterator
	{
		typedef list_node<T> node;
		typedef __list_reverse_iterator<T, Ref, Ptr> self;
		node* _node;

		__list_reverse_iterator(node* n)
			:_node(n)
		{}

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

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

		self& operator++()
		{
			_node = _node->_prev;

			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_prev;

			return tmp;
		}

		self& operator--()
		{
			_node = _node->_next;

			return *this;
		}

		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_next;

			return tmp;
		}

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

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


	template<class T>
	class list
	{
		typedef list_node<T> node;
	public:

		typedef __list_reverse_iterator<T, T&, T*> reverse_iterator;

		typedef __list_const_iterator<T> const_iterator;

		reverse_iterator rbegin()
		{
			return reverse_iterator(_head->_prev);
		}

		reverse_iterator rend()
		{
			return reverse_iterator(_head);
		}
		//......
	}

De fato, implementamos um iterador reverso aqui, mas esse iterador reverso é apenas um iterador reverso para a lista. Podemos implementá-lo em uma versão unificada com base no iterador?

(2) Implementação de simulação do iterador reverso (modo adaptador)

    Lembremos que as implementações de simulação de iteradores de vetores e de listas são diferentes: uma é usar ponteiros diretamente e a outra é encapsular ponteiros brutos para simular o comportamento de ponteiros . De um ponto de vista mais popular, o vetor é contínuo no armazenamento e os iteradores podem ser simulados diretamente pelos ponteiros, enquanto a lista não é contínua no armazenamento; portanto, precisamos encapsular e simular a desreferenciação* e o autoincremento dos ponteiros na classe .+ e outros comportamentos, simulando assim a implementação de iteradores .

     Se quisermos simular a implementação de iteradores reversos, temos que escrever um para cada container? ? ?

    O autor está aqui para avisar com antecedência - não há necessidade . Portanto, o autor esperou que os poucos contêineres anteriores comumente usados ​​terminassem e simulassem a implementação de iteradores reversos!

==================================================== ==================

    Todos seguem o autor para pensarem juntos:

O rbegin do iterador reverso é, na verdade, equivalente ao fim do iterador direto, e o rend é, na verdade, o início do iterador direto. A operação "++" é equivalente à operação "--" do iterador direto etc. Podemos pensar que os iteradores reversos são, na verdade, um iterador avançado "especial"?

Agora que simulamos e implementamos os iteradores diretos um por um, podemos implementar os iteradores reversos uniformemente usando as operações dos iteradores diretos implementados.

Vamos simular a implementação abaixo:

Passamos o iterador direto como um parâmetro de modelo para _cur, para que o iterador reverso possa corresponder automaticamente ao contêiner, para que o iterador reverso possa ser reutilizado uniformemente:

reverse_iteraor.h:

namespace zc
{//List::iteraor
	//vector::iterator
	template<class Iterator,class Ref,class Ptr>
	class ReverseIterator
	{public:
		typedef ReverseIterator<Iterator, Ref, Ptr> Self;
		Iterator _cur;

		ReverseIterator(Iterator it)
		:
			_cur(it)
		{}


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

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

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

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


	};

}

lista.h:

template<class T>
	class list
	{
		typedef list_node<T> node;
	public:
		
		typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
		typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;

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

		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}
//.......
}

Aqui a ênfase principal está na ideia de usar um método para perceber todas as situações, e você pode ler várias vezes!

Resumir:

  • O ponto principal aqui: o modo adaptador é usado.
  • Só precisa adaptar esse iterador reverso em outros containers
  • O código é altamente reutilizável

Desejo sucesso em seus estudos!

Acho que você gosta

Origin blog.csdn.net/m0_67821824/article/details/130032872
Recomendado
Clasificación