学习list

#pragma once

namespace chen
{
	template

	//定义一个list元素的结构体
	struct list_node
	{
		T _data;
		list_node* _next;
		list_node* _prev;

		//写一下这个list类型的构造函数
		list_node(const T& x = T())
			:_data(x);
		    ,_next(nullptr)
			,_prev(nullptr)
		{
	
		}

	};



	普通迭代器
	//template
	//struct _list_iterator
	//{
	//	typedef list_node 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 tmp(*this);
	//		_node = _node->_next;
	//		return tmp;
	//	}
	//	 

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



	//	T& operator*()
	//	{
	//	
	//		return _node->_data;
	//	}


	//	//箭头的重载
	//	T* operator->()
	//	{

	//		return &_node->_data;
	//	}



	//	bool operator!=(const selg& s)
	//	{
	//		return _node != s._node;
	//	}

	//	bool operator==(const selg& s)
	//	{
	//		return !(_node != s._node);
	//	}


	//};

	const 迭代器
	//template
	//struct _list_const_iterator
	//{
	//	typedef list_node Node;
	//	typedef _list_const_iterator self;

	//	Node* _node;

	//	_list_const_iterator(Node* node)
	//		:_node(node)
	//	{}

	//	//前置++
	//	self& operator++()
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}


	//	//前置--
	//	self& operator--()
	//	{
	//		_node = _node->_prev;
	//		return *this;
	//	}



	//	//后置++
	//	self operator++(int)
	//	{
	//		self tmp(*this);
	//		_node = _node->_next;
	//		return tmp;
	//	}


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



	//	const T& operator*()
	//	{

	//		return _node->_data;
	//	}


	//	//箭头的重载
	//	const T* operator->()
	//	{

	//		return &_node->_data;
	//	}



	//	bool operator!=(const selg& s)
	//	{
	//		return _node != s._node;
	//	}

	//	bool operator==(const selg& s)
	//	{
	//		return !(_node != s._node);
	//	}


	//};


//使用模版来来避免迭代器要写两份这个问题

template  //增加两个模版参数,Ref 和 Ptr
struct _list_iterator
{
	typedef list_node 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 tmp(*this);
		_node = _node->_next;
		return tmp;
	}


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



	Ref operator*()
	{

		return _node->_data;
	}


	//箭头的重载
	Ptr operator->()
	{

		return &_node->_data;
	}



	bool operator!=(const selg& s)
	{
		return _node != s._node;
	}

	bool operator==(const selg& s)
	{
		return !(_node != s._node);
	}


};





	template
	class list
	{
		typedef list_node Node;

	public:
		//typedef _list_iterator iterator;
		//typedef _list_const_iterator const_iterator;

		typedef _list_iterator iterator;
		typedef _list_iterator const_iterator;

		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);

		}







		//空初始化
		void empty_init()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;

			_size = 0;
		}
		 

		//无参的构造函数
		list()
		{
			empty_init();
		}


		//拷贝构造函数
		/*在C++中,拷贝构造函数通常接受一个参数,该参数是对当前类类型的引用。在你提供的代码中,拷贝构造函数的参数是const list& lt,这里为什么要使用引用和const关键字的原因如下:

引用参数:拷贝构造函数通常接受引用参数而不是直接传值,这是因为如果传值的话,将会触发另一个拷贝构造函数的调用,从而导致无限递归的问题。通过使用引用参数,可以避免这种递归调用。引用参数允许函数在不复制整个对象的情况下访问对象的内容,这样可以提高效率。

const 关键字:const关键字在参数类型前表示这个引用是常量引用,它告诉编译器在拷贝构造函数内部不允许修改传入的对象。这是因为拷贝构造函数的目的是创建一个与传入对象相同的新对象,而不应该修改原始对象的内容。通过将参数声明为const引用,可以确保拷贝构造函数不会对原始对象进行修改。

所以,拷贝构造函数的参数const list& lt的写法是为了保证安全地创建一个新对象,该对象与传入的对象相同,同时不会修改原始对象的内容。这是C++中拷贝构造函数的常见写法。*/
		list(const list& lt)
		{
			empty_init();
			for (auto e : lt)
			{
				push_back(e);
			}
		}


		运算符重载 = 传统写法
		//list& operator=(const list& lt)
		//{
		//	if (*this != <)
		//	{
		//		clear();
		//		for (auto e : lt)
		//		{
		//			push_back(e);
		//		}
		//	}
		//	return *this;
		//}

		// 现代写法
		/*这段代码是实现了C++中的赋值运算符重载(operator=)以及一个用于交换两个列表对象的成员函数(swap)。这种现代写法遵循了C++的一些最佳实践,包括使用引用、使用标准库中的 std::swap 函数等。

让我们一步一步来解释这段代码:

void swap(list& lt) 函数:

这是一个成员函数,用于交换调用该函数的列表对象(*this)与传入的列表对象 lt 的 _head 成员。这里假设列表对象内部有一个指向链表头的 _head 成员。
list& operator=(list lt) 函数:

这是赋值运算符重载的实现。它将一个 list 对象作为参数传入。
参数 lt 是通过值传递的,这意味着在函数内部会创建 lt 的副本。这是为了确保在赋值发生之前,原始的列表对象(*this)不会受到影响。
接下来,函数调用了 swap(lt),这是之前定义的 swap 函数。这个调用会交换 *this 和 lt 的 _head 成员。
最后,函数返回 *this 的引用,以支持链式赋值操作。
这种写法具有一些优势:

使用引用传递参数可以避免不必要的复制,提高了效率。
使用 std::swap 函数确保了交换的安全性和效率,而不必自行编写交换代码。
返回 *this 的引用支持了链式赋值,例如 a = b = c,其中 a、b 和 c 都是列表对象。
总之,这种现代写法提高了代码的可读性、效率和安全性,并符合C++的最佳实践。*/

		void swap(list& lt)
		{
			std::swap(_head, lt._head);
			std::swap(_size, lt._size);

		}


		list& operator=(list lt)
		{
			swap(lt);
			return *this;
		}



		
		//析构函数
		~list()
		{
			clear();

			delete _head;
			_head = nullptr;
		}


		void clear()
		{
			iterator it;  
			while (it != end())
			{
				it = erase(it); //返回值是下一个位置,所以我们这样写
			}
		}


		//尾插
		void push_back(const T& x)
		{
			//头结点的前一个就是旧尾
			Node* tail = _head->_prev;
			//申请新空间
			Node* newnode = new Node(x);
			//旧尾的next 指向 新尾
			tail->_next = newnode;
			//新尾的prev指向旧尾
			newnode->_prev = tail;
			//新尾的next 指向 头
			newnode->_next = head;
			//头的prev指向 新的尾
			head->_prev = newnode;
		}


		//尾插 第二种写法
		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());
		}

		//插入
		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* newmode = new Node(x);
			
			Node* prev = cur->_prev;

			prev->_next = newnode;
			newnode->prev = prev;

			newnode->_next = cur;
			cur->_prev = newnode;

			++_size;

			return iterator(newnode);
		}


		//删除
		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			delete cur;

			prev->_next = next;
			next->prev = prev;

			--_size;

			return iterator(next);
		}

		size_t size()
		{
			return _size;
		}





	private:
		Node* _head;
		size_t _size;


	};




}

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