stl中的list模拟实现

目录

  • 一、list的简单介绍
  • 二、写出节点的代码
  • 三、模拟实现迭代器(重点)
    • 1、list中的迭代器是怎么实现的
    • 2、编写iterator类的代码
    • 3、对const_iterator进行理解
    • 4、编写const_iterator类的代码
    • 5、对iterator类和const_iterator类进行合并
  • 四、list类进行代码实现

一、list的简单介绍

首先我们要清楚list是一个带头双向循环的链表。

二、写出节点的代码

在下面代码中我们用到了模板,并且用的是struct没有用class,这是因为我们使用struct时相当于这一个类是公开的,当然我们也可以使用class但是得使用友元函数比较麻烦。

	template//这里用到了模板
	struct listnode
	{
		T _data;
		listnode* _next;
		listnode* _prev;
		listnode(const T& x = T())//这里使用的是匿名函数,因为不确定x是什么类型,所以给了一个匿名函数的全缺省
			:_data(x)
			, _next(nullptr)
			, _prev(nullptr)
		{}

	};

三、模拟实现迭代器(重点)

1、list中的迭代器是怎么实现的

我们可以查看stl的源码进行查看,如下:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

我们可以看出list的迭代器就是由链表的一个节点指针来进行控制的,然后再进行对符号的重载。

2、编写iterator类的代码

根据上述可编写以下代码:

template
	struct list_iterator
	{
		typedef listnode Node;
		typedef list_iterator self;
		Node* _node;

		list_iterator(Node* node) {
			_node = node;
		}
		self& operator++() {
			_node = _node->_next;
			return *this;
		}
		self& operator--() {
			_node = _node->_prev;
			return *this;
		}
		self operator++(int) {
			self temp(*this);
			_node = _node->_next;
			return temp;
		}
		self operator--(int) {
			self temp(*this);
			_node = _node->_prev;
			return temp;
		}
		 T* operator->() {
			return &_node->_data;
		}
		 T& operator*() {
			return _node->_data;
		}
		bool operator!=(const self& s) {
			return s._node != _node;
		}
		bool operator==(const self& s) {
			return s._node == _node;
		}

3、对const_iterator进行理解

首先我们要清楚是对谁加const,是对迭代器本身加const还是对迭代器指向的内容加const,我们平常使用const_iteratot时我们可以对迭代器进行++或–,但是不可以对迭代器指向的内容进行修改,由此可以看出我们的const_iterator和iterator是两个类,不可以直接对iterator加const。

4、编写const_iterator类的代码

template
	struct list_const_iterator
	{
		typedef listnode Node;
		typedef list_const_iterator self;
		Node* _node;

		list_iterator(Node* node) {
			_node = node;
		}
		self& operator++() {
			_node = _node->_next;
			return *this;
		}
		self& operator--() {
			_node = _node->_prev;
			return *this;
		}
		self operator++(int) {
			self temp(*this);
			_node = _node->_next;
			return temp;
		}
		self operator--(int) {
			self temp(*this);
			_node = _node->_prev;
			return temp;
		}
		const T* operator->() {
			return &_node->_data;
		}
		const T& operator*() {
			return _node->_data;
		}
		bool operator!=(const self& s) {
			return s._node != _node;
		}
		bool operator==(const self& s) {
			return s._node == _node;
		}
	};

5、对iterator类和const_iterator类进行合并

在编写iterator类和const_iterator类我们发现除了下面的代码不一样其余的代码都是一样的。

在这里插入图片描述

在这里插入图片描述

但是这样写的话,代码就会冗余,所以这时我们用一个类模板,对代码进行修改,如下:

template
	struct list_iterator
	{
		typedef listnode Node;
		typedef list_iterator self;
		Node* _node;

		list_iterator(Node* node) {
			_node = node;
		}
		self& operator++() {
			_node = _node->_next;
			return *this;
		}
		self& operator--() {
			_node = _node->_prev;
			return *this;
		}
		self operator++(int) {
			self temp(*this);
			_node = _node->_next;
			return temp;
		}
		self operator--(int) {
			self temp(*this);
			_node = _node->_prev;
			return temp;
		}
		Ptr operator->() {
			return &_node->_data;
		}
		Ref operator*() {
			return _node->_data;
		}
		bool operator!=(const self& s) {
			return s._node != _node;
		}
		bool operator==(const self& s) {
			return s._node == _node;
		}
	};

四、list类进行代码实现

这里主要是写构造函数、拷贝构造、赋值拷贝、析构函数、迭代器的begin()和end()的实现,以及其他功能的实现。

代码如下:

template
	class list {
		typedef listnode Node;
	public:
		typedef list_iterator iterator;
		typedef list_iterator const_iterator;
		void empty_init() {
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			_size = 0;
		}
		const_iterator begin() const{
			return _head->_next;
		}
		const_iterator end() const{
			return _head;
		}
		iterator begin() {
			return _head->_next;
		}
		iterator end() {//返回的是最后一个节点的后一个,所以返回的是头节点
			return _head;
		}
		list() {
			empty_init();
		}
		list(list& it) {
			empty_init();
			for (auto e : it) {
				push_back(e);
			}
		}
		void swap(list& It) {
			std::swap(_head, It->_head);
			std::swap(_size, It->_size);
		}
		list& operator=(list& It)
		{
			swap(It);
			return *this;
		}
		~list()
		{
			clear();
			delete(_head);
			_size = 0;
		}
		void push_back(const T& x) {
			insert(end(), x);
		}
		void push_front(const T& x) {
			insert(begin(), x);
		}
		void pop_front() {
			erase(begin());
		}
		void pop_back() {
			erase(--end());
		}
		void clear() {
			while (!empty()) {
				pop_back();
			}
		}
		bool empty() {
			return _size == 0;
		}
		size_t size() {
			return _size;
		}
		iterator erase(iterator pos) {
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			prev->_next = next;
			next->_prev = prev;
			delete cur;
			--_size;
			return iterator(next);
		}
		iterator insert(iterator pos, T x) {
			Node* cur = pos._node;
			Node* newNode = new Node(x);
			Node* prev = cur->_prev;
			prev->_next = newNode;
			newNode->_prev = prev;
			newNode->_next = cur;
			cur->_prev = newNode;
			
			++_size;
			return iterator(newNode);
		}
	private:
		Node* _head;
		size_t _size;
	};

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/28d4d9659a.html