STL:list的模拟实现(迭代器失效探讨)

为什么重新设计list迭代器

对迭代器解引用,我们希望拿到的是指针所指向的值域,而直接解引用拿到的是指针所指向的节点
**对list指针++和- -

迭代器:

  • 提供一种方法,使其能够按照顺序访问容器(聚合物)所含的各个元素,并且不用暴露容器内部的表述方式

本质

  • 就是指针或者对指针的封装

实现

  • 对原生态指针进行封装,即实现一个迭代器的类
  • 在容器中给迭代器取别名:typedef 迭代器类型 iterator
  • 在容器中增加begin和end的方法

使用:指针所具备的操作迭代器都需要有

  • *和->
  • 移动++,–
  • 比较==,!=

用户只和list类进行交互,在list类中实例化迭代器的模板

先构造list的每一个节点

template<class T>
struct ListNode
{
	ListNode* prev;
	ListNode* next;
	T val;

	ListNode(const T& value = T())
		:prev(nullptr)
		, next(nullptr)
		, val(val)
	{}
};

正向迭代器设计

typedef P P
在反向迭代器类中没有P和R类型,但是在正向迭代器中有,需要去找

template<class T, class P, class R>
struct ListIterator
{
	typedef P P;
	typedef R R;
	typedef ListNode<T> Node;
	typedef ListIterator<T, P, R> iterator;

	Node* _pNode;//成员变量

	ListIterator(Node* pNode=nullptr)
		:_pNode(pNode)
	{}
	
	R operator*()
	{
		return _pNode->val;
	}
	
	P operator&()
	{
		return &(_pNode->val);
	}
	
	iterator& operator++()
	{
		_pNode = _pNode->next;
		return *this;
	}
	
	iterator operator++(int)
	{
		iterator tmp(*this);
		_pNode = _pNode->next;
		return tmp;
	}
	
	iterator& operator--()
	{
		_pNode = _pNode->prev;
		return *this;
	}
	
	iterator operator--(int)
	{
		iterator tmp(*this);
		_pNode = _pNode->prev;
		return tmp;
	}
	
	bool operator!=(const iterator& it)const
	{
		return _pNode != it->_pNode;
	}
	
	bool operator==(const iterator& it)const
	{
		return _pNode == it->_pNode;
	}
};

反向迭代器

反向迭代器是通过正向迭代器实例化出来的

加typename的原因

  • P和R是在正向迭代器中的
  • 静态成员变量也是按照类名::静态成员变量名访问的
  • 如果不加typename修饰,编译器就不知道iterator后的是类型还是静态成员变量
template<class iterator>
struct rListIterator
{
	iterator _it;
	typename typedef iterator::R R;
	typename typedef iterator::P P;

	typedef rListIterator<iterator> riterator;
	
	R operator*()
	{
		iterator tmp = _it;
		tmp--;
		return *tmp;
	}

	P operator&()
	{
		return _it->_pNode->val;
	}

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

	riterator operator++(int)
	{
		_it--;
		return *this;
	}

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

	riterator operator--(int)
	{
		_it++;
		return *this;
	}

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

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

list类

template<class T>
	class list
	{
	private:
	    Node* _head;//成员变量
		void CreateHeadNode()
		{
			_head = new Node();
			_head->next = _head;
			_head->prev = _head;
		}
		
	public://确定类型,实例化模板类
		typedef ListNode<T> Node;
		typedef ListItertor<T, T*, T&> iterator;
		typedef ListItertor<T, const T*, const T&> const_iterator;

		typedef ListReverseIterator<iterator> reverse_iterator;
		typedef ListReverseIterator<const_iterator> const_reverse_iterator;

	public:
	//
	// 构造
		list()
		{
			CreateHeadNode();
		}

		list(int n, const T& val = T())
		{
			CreateHeadNode();
			for (int i = 0; i < n; ++i)
			{
				push_back(val);
			}
		}

		template<class Iterator>
		list(Iterator first, Iterator last)
		{
			CreateHeadNode();
			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		list(const list<T>& L)
		{
			CreateHeadNode();
			for (auto e : L)
			{
				push_back(e);
			}
		}

		list<T> operator=(list<T> L)
		{
			this->swap(L);
			return *this;
		}

		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}

		/
		// 正向迭代器
		iterator begin()
		{
			return iterator(_head->next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		const_iterator begin()const
		{
			return const_iterator(_head->next);
		}

		const_iterator end()const
		{
			return const_iterator(_head);
		}

		// 反向迭代器
		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}

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

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

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

		///
		// 容量相关
		size_t size()const
		{
			size_t count = 0;
			Node* cur = _head->next;
			while (cur != _head)
			{
				++count;
				cur = cur->next;
			}
			return count;
		}

		bool empty()const
		{
			return _head == _head->next;
		}

		void resize(size_t newsize, const T& val = T())
		{
			size_t oldsize = size();
			if (newsize < oldsize)
			{
				// 将原链表中节点个数缩减到newsize个
				for (size_t i = newsize; i < oldsize; ++i)
				{
					pop_back();
				}
			}
			else
			{
				// 将原链表中有效节点的个数增加到newsize个
				for (size_t i = oldsize; i < newsize; ++i)
				{
					push_back(val);
				}
			}
		}

		
		// 元素访问
		T& front()
		{
			return _head->next->val;
		}

		const T& front()const
		{
			return _head->next->val;
		}

		T& back()
		{
			return _head->prev->val;
		}

		const T& back()const
		{
			return _head->prev->val;
		}

		///
		// 修改
		void push_front(const T& val)
		{
			insert(begin(), val);
		}

		void pop_front()
		{
			if (empty())
				return;

			erase(begin());
		}

		void push_back(const T& val)
		{
			insert(end(), val);
		}

		void pop_back()
		{
			if (empty())
				return;

			auto pos = end();
			--pos;
			erase(pos);
		}

		iterator insert(iterator Itpos, const T& val)
		{
			Node* pos = Itpos._pNode;
			Node* newNode = new Node(val);
			newNode->next = pos;
			newNode->prev = pos->prev;
			newNode->prev->next = newNode;
			pos->prev = newNode;
			return newNode;
		}

		iterator erase(iterator Itpos)
		{
			Node* pos = Itpos._pNode;
			if (pos == _head)
				return pos;

			// 将pos节点从链表中拆除下来
			pos->prev->next = pos->next;
			pos->next->prev = pos->prev;

			Node* retNode = pos->next;
			delete pos;
			return retNode;
		}

		void clear()
		{
			Node* cur = _head->next;
			// 采用头删法
			while (cur != _head)
			{
				_head->next = cur->next;
				delete cur;
				cur = _head->next;
			}

			_head->next = _head;
			_head->prev = _head;
		}

		void swap(list<T>& L)
		{
			std::swap(_head, L._head);
		}
	};

你可能感兴趣的:(STL,c++,list)