【c++list】list的迭代器实现和一些特殊使用

目录

1.带头双向循环链表的迭代器实现

                        链表的基础框架(初始化和尾插)

2.迭代器

                实现迭代器

                可读可写和可读的迭代器

                解决方法

3.list的一些特殊使用

                使用数组初始化(通用)

                迭代器失效


1.带头双向循环链表的迭代器实现

                        链表的基础框架(初始化和尾插)

  • begin和end返回先要iterator构造函数初始化
#include
using namespace std;

namespace lj
{
	template
	struct _list_node//struct全为公有
	{
		T _val;
		_list_node* _prev;
		_list_node* _next;
		_list_node(const T x = T())
			:_val(x)
			,_prev(nullptr)
			,_next(nullptr)
		{}
	};

	template
	class list
	{
		typedef _list_node node;
	public:
        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);
		}

		list()//构造函数
		{
			_head = new node;
			_head -> _prev = _head;
			_head -> _next = _head;
		}
		void push_back(const T& x)//尾插
		{
			node* newnode = new node(x);
			node* tail = _head->_prev;
			
			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;
		}

	private:
		node* _head;
	};

2.迭代器

                实现迭代器

  • 为什么要自己实现迭代器

【c++list】list的迭代器实现和一些特殊使用_第1张图片

  • 实现了可读可写的迭代器

【c++list】list的迭代器实现和一些特殊使用_第2张图片

	template
	struct _list_iterator
	{
		typedef _list_node node;
		typedef _list_iterator self;

		node* _pnode;

		_list_iterator(node* pnode)//构造函数
			:_pnode(pnode)
		{}
		T operator*()
		{
			return _pnode->_val;
		}
		bool operator!=(const self& s)const
		{
			return _pnode != s._pnode;
		}
		bool operator==(const self& s) const
		{
			return _pnode == s._pnode;
		}
		self& operator++()
		{
			_pnode = _pnode->_next;
			return *this;
		}

		// it++ -> it.operator++(&it, 0)
		self operator++(int)
		{
			self tmp(*this);
			_pnode = _pnode->_next;
			return tmp;
		}

		self& operator--()
		{
			_pnode = _pnode->_prev;
			return *this;
		}

		self operator--(int)
		{
			self tmp(*this);
			_pnode = _pnode->_prev;
			return tmp;
		}
	};
void test_list()
	{
		list lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);

		list::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << " ";
			++it;
		}
		cout << endl;
	}

                可读可写和可读的迭代器

  • 把写的_list_node类,给const_iterator单独写一个类
  • 那么代码出了operator*以外基本相同,要冗杂了

【c++list】list的迭代器实现和一些特殊使用_第3张图片

                解决方法

  • -list_iterator是一个类模板,可以实例化出两个例子;

【c++list】list的迭代器实现和一些特殊使用_第4张图片

template
	struct _list_iterator
	{
		typedef _list_node node;
		typedef _list_iterator self;

		node* _pnode;

		_list_iterator(node* pnode)//构造函数
			:_pnode(pnode)
		{}
		Ref operator*()
		{
			return _pnode->_val;
		}
		bool operator!=(const self& s)const
		{
			return _pnode != s._pnode;
		}
		bool operator==(const self& s) const
		{
			return _pnode == s._pnode;
		}
		self operator++()
		{
			_pnode = _pnode->_next;
			return *this;
		}

		// it++ -> it.operator++(&it, 0)
		self operator++(int)
		{
			self tmp(*this);
			_pnode = _pnode->_next;
			return tmp;
		}

		self& operator--()
		{
			_pnode = _pnode->_prev;
			return *this;
		}

		self operator--(int)
		{
			self tmp(*this);
			_pnode = _pnode->_prev;
			return tmp;
		}
	};
class list
	{
		typedef _list_node node;
	public:
		typedef _list_iterator iterator;//类模板会实例化两个例子
		typedef _list_iterator const_iterator;
    };

3.list的一些特殊使用

                使用数组初始化(通用)

  • 原生指针可以当做天然的迭代器使用,其实vector/string的的迭代器也是原生指针
#include
#include
#include


using namespace std;

void test_list1()
{
    int a[] = { 1,2,3,4 };
	//原生指针可以当做天然的迭代器使用,其实vector/string的的迭代器也是原生指针
	list::iterator it = lt1.begin();//InputIterator first, InputIterator last
	while (it != lt1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}

                迭代器失效

  • list因为底层结构insert不会导致pos迭代器失效
  • list因为底层结构erase会导致pos迭代器失效,野指针
  • 【c++list】list的迭代器实现和一些特殊使用_第5张图片

list lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//list因为底层结构insert不会导致pos迭代器失效
	lt.insert(pos, 30);
	//list因为底层结构erase会导致pos迭代器失效,野指针
	lt.erase(pos);

你可能感兴趣的:(c++,c++,链表)