[C++] Simulation implementation of list in STL (addition, deletion, checking and modification, iterator encapsulation, operator overloading)


foreword

The underlying structure of the list is a two-way circular linked list with a leading node

General framework:

namespace simulation {
    
    
	template <class T>
	struct list_node {
    
    
	//成员函数
	};
template<class T,class Ref,class Ptr>
	struct _list_iterator {
    
    
	//成员函数
	};

template<class T>
	class list {
    
    
		typedef list_node<T> Node;
	public:
		typedef _list_iterator<T, T&, T*> iterator;
		typedef _list_iterator<T, const T&, const T*>  const_iterator;
	//成员函数
		private:
		Node* _head;
		size_t _size;
	};
	}
	

1. Encapsulation of nodes (list_node)

template <class T>
	struct list_node {
    
    
		//带头的双向循环链表
		//在类模板中:
		//类名不等于类型,所以定义指针时类名要显示实例化
		list_node<T>* _prev;
		list_node<T>* _next;
		T _val;
		list_node(const T&val=T())
			//T()相当于调用构造函数;
			:_prev(nullptr)
			,_next(nullptr)
			,_val(val)
		{
    
    }
	};

2. Encapsulation of iterators (_list_iterator)

Because the data of the list is not in a continuous memory (like vector, string),
we cannot use native pointers as iterators. We have to design an iterator by ourselves
, and implement its ++ and comparison operations by ourselves.

1. Definition of class template:

//设计const迭代器:可以把迭代器理解为类似指针
	// 错误示范: typedef const __list_iterator<T> const_iterator;
	// 这样设计const迭代器是不行的,因为const迭代器期望指向内容不能修改
	// 这样设计是迭代器本身不能修改
	 
	//为了设计不那么繁琐,我们传入三个模板参数
	template<class T,class Ref,class Ptr>
	//相当于:
	// typedef __list_iterator<T, T&, T*> iterator;
		// typedef __list_iterator<T, const T&, const T*> const_iterator;

2. Constructor

typedef list_node<T> Node;
		typedef _list_iterator<T, Ref, Ptr> self;
		Node* _node;//成员变量

		_list_iterator(Node* node)
			:_node(node)
		{
    
    }

3. Front ++, post ++

self& operator++() {
    
    //前置++
		//typedef _list_iterator<T, Ref, Ptr> self;
			_node = _node->_next;
			return *this;
		}
		self operator++(int) {
    
    //后置++
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

4. Front –, Rear –

self& operator--() {
    
    
			_node = _node->_prev;
			return *this;
		}
		self operator--(int) {
    
    
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

5. Dereference (operator*())

Ref operator*() {
    
    
		//因为可能为const T&类型或者T&类型
		//为了避免繁琐,使用模板参数里面的Ref
		//编译器根据不同的类型会生成对应的函数
			return _node->_val;
		}

6. -> Overloading (operator->())

    //template<class T,class Ref,class Ptr>
	//相当于:
	// typedef __list_iterator<T, T&, T*> iterator;
	// typedef __list_iterator<T, const T&, const T*> const_iterator;
Ptr operator->() {
    
    
			return&_node->_val;
		}

insert image description here

7. Overloading of comparison operators:

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

Three, list member function

1. Constructor

typedef list_node<T> Node;
	public:
		typedef _list_iterator<T, T&, T*> iterator;
		typedef _list_iterator<T, const T&, const T*>  const_iterator;
		void empty_init() {
    
    
			_size = 0;
			_head = new Node;
			_head->_prev = _head;
			_head->_next = _head;
		}
		list() {
    
    //构造函数
			empty_init();
		}
   private
         Node*_head;//哨兵位
         size_t _size;

2.begin(),end()

         iterator begin() {
    
    
         //begin()为哨兵位下一个
			return _head->_next;
		}
		const_iterator begin()const {
    
    
			return _head->_next;
		}
		//end()为哨兵位
		iterator end() {
    
    
			return _head;
		}
		const_iterator end()const {
    
    
			return _head;
		}

3. Insert (insert) insert at a position before pos

When inserting into the list, the iterator of the list will not be invalidated. It will only be invalidated when it is deleted, and only the iterator pointing to the deleted node will be invalidated, and other iterators will not be affected.

iterator insert(iterator pos, const T& x) {
    
    
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* newnode = new Node(x);
			newnode->_prev = prev;
			newnode->_next = cur;
			prev->_next = newnode;
			cur->_prev = newnode;
			++_size;

			//返回指向第一个新插入元素的迭代器。
			return newnode;
		}

4. delete (erase)

iterator erase(iterator pos) {
    
    
			assert(pos != end());
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			delete cur;
			prev->_next = next;
			next->_prev = prev;
			--_size;
			//返回被删除节点的下一个位置
			return next;
		}

5. Tail plug tail delete

	void push_front(const T& x) {
    
    
			insert(begin(), x);
		}
		void pop_back() {
    
    
			erase(--end());
		}

6. Head plug delete

void push_back(const T&x) {
    
    
			insert(end(), x);
		}
void pop_front() {
    
    
			erase(begin());
		}

7. Destructor

        void clear() {
    
    
			 
			iterator it = begin();
			while (it != end()) {
    
    
				it = erase(it);
			}
			_size = 0;
		}
		~list() {
    
    
			clear();
			delete _head;
			_head = nullptr;
		}

8. Assignment operator overloading

void swap(list<T>&lt){
    
    
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);
		}
		list<T>operator=(list<T> lt) {
    
    
			swap(lt);
			return *this;
		}

9. Copy constructor

     list(const list<T>& lt) {
    
    
			empty_init();
			_size = lt._size;
			for (auto &ch : lt) {
    
    
				push_back(ch);
			}
			
		}

10. Size

size_t size() {
    
    
			return _size;
		}

Guess you like

Origin blog.csdn.net/m0_74774759/article/details/131961373