STL-list实现(注释详解)

Posted 在下赵某人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL-list实现(注释详解)相关的知识,希望对你有一定的参考价值。

 

 

#include<iostream>
#include<assert.h>
using namespace std;

namespace zzd

	template<class T>
	struct list_node
	
		成员函数
		//构造函数
		list_node(const T& data = T())
			:_prev(nullptr)
			, _next(nullptr)
			, _data(data)
		
		//~__list_node()-->不用自己写。因为:编辑器生成的析构函数,对于内置类型不处理,
		//                                 但对于自定义类型的成员,会调用该它自己的析构函数。

		成员变量
		list_node<T>* _prev;
		list_node<T>* _next;
		T _data;
	;

	// 迭代器---> 用一个类去封装了节点的指针
	// iterator - <T,T&,T*>
	// const_iterator - <T, const T&, const T*>
	template<class T, class Ref, class Ptr>
	struct list_iterator
	
		typedef list_node<T> Node;
		typedef list_iterator<T, Ref, Ptr> self;
		成员函数
		//构造函数
		list_iterator(Node* node)
			:it_pnode(node)
		
		//拷贝构造与赋值重载不需要自己写,默认生成就可以,因为迭代器指向的资源不属于它,故完成浅拷贝就可以了。
		//析构函数也不需要自己写因为list中只有一个 Node指针 的成员变量,无管理的资源
		
		//运算符重载
		//注:*和-> 都是想实现直接操作Node里的成员变量:T _data; 
		Ref operator*()
		
			return it_pnode->_data;
		
		// 注意:-> 的返回值类型是 T*
		Ptr operator->()
		
			return &it_pnode->_data;
		
		// ++it
		self& operator++()
		
			it_pnode = it_pnode->_next;
			return *this;
		
		// it++
		self operator++(int)
		
			self tmp(*this);//拷贝构造,用户未写,编辑器自动生成默认构造 完成浅拷贝
			it_pnode = it_pnode->_next;
			return tmp;
		
		// --it
		self& operator--()
		
			it_pnode = it_pnode->_prev;
			return *this;
		
		// it--
		self operator--(int)
		
			self tmp(*this);
			it_pnode = it_pnode->_prev;
			return tmp;
		

		bool operator==(const self& it)
		
			return it_pnode == it.it_pnode;
		

		bool operator!=(const self& it)
		
			return it_pnode != it.it_pnode;
		

		成员变量
		Node* it_pnode;
	;
	
	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;
		成员函数
		//默认构造
		list()
		
			//带头双向循环
			list_phead = new Node;
			list_phead->_next = list_phead;
			list_phead->_prev = list_phead;
		
		//迭代器区间构造
		template<class input_iterator>
		list(input_iterator first, input_iterator last)
		
			list_phead = new Node;
			list_phead->_next = list_phead;
			list_phead->_prev = list_phead;

			while (first != last)
			
				push_back(*first);
				first++;
			
		
		//拷贝构造
		// list<T> it2(it1)
		1、传统写法

		//list(const list<T>& it)//传引用
		//
		//	//以下三步只要是构造函数就要写,因为要构造一个新的list,它的头结点要先初始化。
		//	list_phead = new Node;
		//	list_phead->_next = list_phead;
		//	list_phead->_prev = list_phead;
		//
		//	for (auto& e : it)
		//	
		//		push_back(e);
		//	
		//	范围for会变成:
		//	//iterator it = begin(); ---> 不用加list<T>::的类域指定
		//	//while (it != end())
		//	//
		//	//	push_back(*it);
		//	//	it++;
		//	//
		//

		//2、现代写法
		list(const list<T>& it)//传引用
		
			list_phead = new Node;
			list_phead->_next = list_phead;
			list_phead->_prev = list_phead;

			list tmp(it.begin(), it.end());//调用构造函数 构造一个list tmp
			std::swap(list_phead, tmp.list_phead);
		

		//赋值重载 --- 现代写法
		//lt1 = lt2
		list<T> operator=(list<T> it)//lt用的是传值,调用了一次拷贝构造
		
			std::swap(list_phead, it.list_phead);
			return *this;
			//最后lt析构时还会释放原来lt1中的资源	
		

		//析构函数
		~list()
		
			clear();
			delete(list_phead);//删除头结点
			list_phead = nullptr;
		
		iterator begin()
		
			return iterator(list_phead->_next);
		
		iterator end()
		
			return iterator(list_phead);
		
		const_iterator begin() const //const修饰的类对象只能调用const修饰的成员函数
		
			return const_iterator(list_phead->_next); //调用const修饰的成员函数则决定构造并返回的迭代器类型为const_iterator
		
		const_iterator end() const//构造并返回的迭代器类型为const_iterator,则说明迭代器类模板参数为<T, const T&, const T*>
		
			return const_iterator(list_phead); //迭代器类模板参数为<T, const T&, const T*>即迭代器类中:Ref, Ptr换成了T&, T*
		
		// Ref, Ptr换成了T&, T*,即迭代器的*、->返回值用const修饰了,则*和->迭代器变成了只读。
		//且迭代器的其他运算符重载返回值为const_iterator
		iterator insert(iterator pos, const T& x)
		
			Node* cur = pos.it_pnode;
			Node* prev = cur->_prev;
			Node* new_node = new Node(x);

			prev->_next = new_node;
			new_node->_prev = prev;
			new_node->_next = cur;
			cur->_prev = new_node;
			//构造匿名对象
			//也可以--->return newnode;--->单参的构造函数支持隐式类型转换
			return iterator(new_node);//insert返回新插入元素的迭代器
		

		void push_back(const T& x)
		
			insert(end(), x);
		
		void push_front(const T& x)
		
			insert(begin(), x);
		

		iterator erase(iterator pos)
		
			assert(pos != end());//头节点不能删

			Node* cur = pos.it_pnode;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			delete cur;//cur为Node*,这里会先对cur调用Node的析构函数,然后释放cur指向的空间。
			prev->_next = next;
			next->_prev = prev;
			return iterator(next);//erase返回被删除元素的后一个位置的迭代器
		

		void pop_back()
		
			erase(--end());
		
		void pop_front()
		
			erase(begin());
		

		void clear()
		
			iterator it = begin();
			while (it != end())
			
				it = erase(it);//erase返回被删除元素的后一个位置的迭代器
			
		

		size_t size()
		
			size_t i = 0;
			iterator it = begin();
			while (it != end())
			
				i++;
				it++;
			
			return i;
		
		bool empty()
		
			return begin() == end();
		

	private:
		成员变量
		Node* list_phead;
	;

	void print(const list<int>& l)
	
		for (auto e : l)
		
			cout << e << " ";
		
		cout << endl;
	

	void test1()
	
		list<int> l;
		l.push_back(1);
		l.push_back(2);
		l.push_back(3);
		l.push_back(4);
		l.push_back(5);
		print(l);
		l.pop_back();
		print(l);
		//for (auto& e : l)
		//
		//	cout << e << " ";
		//
		//cout << endl;
		l.clear();
		print(l);
		l.push_back(1);
		l.push_back(2);
		l.push_back(3);
		l.push_back(4);
		list<int> l2(l);
		cout << "l2:";
		print(l2);
		list<int> l3;
		l3.push_back(1);
		l3 = l2;
		cout << "l3:";
		print(l3);
	


int main()

	zzd::test1();
	return 0;

 

 求赞,知道你们不会给,就是走个流程

以上是关于STL-list实现(注释详解)的主要内容,如果未能解决你的问题,请参考以下文章

STL-list实现(注释详解)

STL-list 链表

vbscript 各种自定义代码片段 - 有关详细信息,请参阅注释

C++提高编程STL-list容器

C语言—实现扫雷游戏(注释详解)

排序:Java实现大顶堆和二叉树的广度优先遍历原理及代码注释详解