C++初阶——简单实现list

发布于:2025-02-25 ⋅ 阅读:(8) ⋅ 点赞:(0)

目录

1、前言

2、List.h

3、Test.cpp


1、前言

1. 简单实现std::list,重点:迭代器,类模板,运算符重载。

2. 并不是,所有的类,都需要深拷贝,像迭代器类模板,只是用别的类的资源,不需要深拷贝。

3. 高度相似 -> 模板。

4. 迭代器的种类

功能:iterator,reverse_iterator,const_iterator,const_reverse_iterator。

按结构(性质):决定可以使用什么算法

单向(Forward):forward_list/unordered_map/unordered_set    ++

双向(Bidirectional):list/map/set    ++/--

随机(Random Access):vector/string/deque    ++/--/+/-

2、List.h

#pragma once

#include <iostream>
#include <list>
#include <assert.h>

using namespace std;

namespace Lzc
{
	template<class T>
	struct list_node
	{
		typedef list_node<T> Node;
		T _data;
		Node* _next;
		Node* _prev;
		list_node(const T& data = T())
			:_data(data)
			, _next(nullptr)
			, _prev(nullptr)
		{}
	};

	//template<class T>
	//struct list_iterator
	//{
	//	typedef list_node<T> Node;
	//	typedef list_iterator<T> iterator;
	//	Node* _node;
	//	list_iterator(Node* node)
	//		:_node(node)
	//	{}
	//	T& operator*() const
	//	{
	//		return _node->_data;
	//	}
	//	T* operator->() const
	//	{
	//		return &_node->_data;
	//	}
	//	iterator& operator++() // 前置++
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}
	//	iterator operator++(int) // 后置++
	//	{
	//		iterator tmp(_node);
	//		_node = _node->_next;
	//		return tmp;
	//	}
	//	iterator& operator--() // 前置--
	//	{
	//		_node = _node->_prev;
	//		return *this;
	//	}
	//	iterator operator--(int) // 后置--
	//	{
	//		iterator tmp(_node);
	//		_node = _node->_prev;
	//		return tmp;
	//	}
	//	bool operator!=(const iterator& it) const
	//	{
	//		return _node != it._node;
	//	}
	//  bool operator==(const iterator& it) const
	//	{
	//		return _node == it._node;
	//	}
	//};

	//template<class T>
	//struct list_const_iterator
	//{
	//	typedef list_node<T> Node;
	//	typedef list_const_iterator<T> const_iterator;
	//	Node* _node;
	//	list_const_iterator(Node* node)
	//		:_node(node)
	//	{
	//	}
	//	const T& operator*() const
	//	{
	//		return _node->_data;
	//	}
	//	const T* operator->() const
	//	{
	//		return &_node->_data;
	//	}
	//	const_iterator& operator++() // 前置++
	//	{
	//		_node = _node->_next;
	//		return *this;
	//	}
	//	const_iterator operator++(int) // 后置++
	//	{
	//		iterator tmp(_node);
	//		_node = _node->_next;
	//		return tmp;
	//	}
	//	const_iterator& operator--() // 前置--
	//	{
	//		_node = _node->_prev;
	//		return *this;
	//	}
	//	const_iterator operator--(int) // 后置--
	//	{
	//		iterator tmp(_node);
	//		_node = _node->_prev;
	//		return tmp;
	//	}
	//	bool operator!=(const const_iterator& it) const
	//	{
	//		return _node != it._node;
	//	}
	// 	bool operator==(const const_iterator& it) const
	//	{
	//		return _node == it._node;
	//	}
	//};

	// 高度相似->模板
	template<class T, class Ref, class Ptr>
	struct list_iterator
	{
		typedef list_node<T> Node;
		typedef list_iterator<T, Ref, Ptr> Self;
		Node* _node;

		list_iterator(Node* node) // 就是要指针,浅拷贝,没问题
			:_node(node)
		{}
		Ref operator*() const
		{
			return _node->_data;
		}
		Ptr operator->() const
		{
			return &_node->_data;
		}
		Self& operator++() // 前置++
		{
			_node = _node->_next;
			return *this;
		}
		Self operator++(int) // 后置++
		{
			Self tmp(_node);
			_node = _node->_next;
			return tmp;
		}
		Self& operator--() // 前置--
		{
			_node = _node->_prev;
			return *this;
		}
		Self operator--(int) // 后置--
		{
			Self tmp(_node);
			_node = _node->_prev;
			return tmp;
		}
		bool operator!=(const Self& it) const
		{
			return _node != it._node;
		}
		bool operator==(const Self& it) const
		{
			return _node == it._node;
		}
	};

	template<class T>
	class list
	{
		typedef list_node<T> Node; // 只有list类的成员函数或者友元才能使用这个类型别名
	public:
		typedef list_iterator<T, T&, T*> iterator;
		typedef list_iterator<T, const T&, const T*> const_iterator;
		//typedef list_iterator<T> iterator;
		//typedef list_const_iterator<T> const_iterator;

		iterator begin()
		{
			return _head->_next; // 隐式类型转换
		}
		iterator end()
		{
			return _head;
		}
		const_iterator begin() const
		{
			return _head->_next;
		}
		const_iterator end() const
		{
			return _head;
		}

		void empty_initialize()
		{
			_head = new Node;
			_head->_next = _head->_prev = _head;
			_size = 0;
		}
		list()
		{
			empty_initialize();
		}
		list(initializer_list<T> lt)
		{
			empty_initialize();
			for (auto& e : lt)
			{
				push_back(e);
			}
		}
		list(const list& lt)
		{
			// list();构造函数不能被直接调用
			empty_initialize();
			for (auto& e : lt)
			{
				push_back(e);
			}
		}

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

		void clear()
		{
			while (!empty())
			{
				pop_front();
			}
		}

		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
			_size = 0;
		}

		size_t size() const
		{
			return _size;
		}

		bool empty() const
		{
			return _size == 0;
		}

		void push_back(const T& val)
		{
			insert(end(), val);
		}

		void push_front(const T& val)
		{
			insert(begin(), val);
		}

		iterator insert(iterator pos, const T& val);

		void pop_front()
		{
			erase(begin());
		}
		void pop_back()
		{
			erase(_head->_prev);
		}

		iterator erase(iterator pos);

	private:
		Node* _head;
		size_t _size;
	};

	template<class T>
	typename list<T>::iterator list<T>::insert(iterator pos, const T& val)
	{
		Node* newNode = new Node(val);
		Node* cur = pos._node;
		Node* prev = cur->_prev;

		prev->_next = newNode;
		newNode->_prev = prev;
		newNode->_next = cur;
		cur->_prev = newNode;

		++_size;

		return newNode;

	}

	template<class T>
	typename list<T>::iterator list<T>::erase(iterator pos)
	{
		assert(pos != _head);
		Node* cur = pos._node;
		Node* next = cur->_next;
		Node* prev = cur->_prev;

		prev->_next = next;
		next->_prev = prev;
		delete cur;

		--_size;

		return next;
	}

	template<class Container>
	void print_Container(const Container& con)
	{
		for (auto& e : con)
		{
			cout << e << " ";
		}
		cout << endl;
	}
}

3、Test.cpp

#include "List.h"

namespace Lzc
{
	struct AA
	{
		int _a1 = 1;
		int _a2 = 1;
	};
	void test_list1()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);

		list<int>::iterator it = lt.begin();
		while (it != lt.end())
		{
			*it += 10;

			cout << *it << " ";
			++it;
		}
		cout << endl;

		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;
		print_Container(lt);

		list<AA> lta;
		lta.push_back(AA());
		lta.push_back(AA());
		lta.push_back(AA());
		lta.push_back(AA());
		list<AA>::iterator ita = lta.begin();
		while (ita != lta.end())
		{
			//cout << (*ita)._a1 << ":" << (*ita)._a2 << endl;
			cout << ita->_a1 << ":" << ita->_a2 << endl;

			// 特殊处理,本来应该是两个->才合理,为了可读性,省略了一个->
			// cout << ita.operator->()->_a1 << ":" << ita.operator->()->_a2 << endl;
			
			++ita;
		}
		cout << endl;
	}

	void test_list2()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);

		// insert后,it还指向begin(),没有扩容的概念,不失效
		list<int>::iterator it = lt.begin();
		lt.insert(it, 10); 
		*it += 100;

		print_Container(lt);

		// erase后,it为野指针,及时更新
		// 删除所有的偶数
		it = lt.begin();
		while (it != lt.end())
		{
			if (*it % 2 == 0)
			{
				it = lt.erase(it);
			}
			else
			{
				++it;
			}
		}

		print_Container(lt);
	}

	void test_list3()
	{
		list<int> lt1;
		lt1.push_back(1);
		lt1.push_back(2);
		lt1.push_back(3);
		lt1.push_back(4);

		list<int> lt2(lt1);

		print_Container(lt1);
		print_Container(lt2);

		list<int> lt3;
		lt3.push_back(10);
		lt3.push_back(20);
		lt3.push_back(30);
		lt3.push_back(40);

		lt1 = lt3;
		print_Container(lt1);
		print_Container(lt3);
	}

	void func(const list<int>& lt)
	{
		print_Container(lt);
	}

	void test_list4()
	{
		// 直接构造
		list<int> lt0({ 1,2,3,4,5,6 });
		// 隐式类型转换
		list<int> lt1 = { 1,2,3,4,5,6,7,8 };
		const list<int>& lt3 = { 1,2,3,4,5,6,7,8 };

		func(lt0);
		func({ 1,2,3,4,5,6 });

		print_Container(lt1);

		// template<class T> class initializer_list;
		// { 10, 20, 30 }是一种initializer_list<int>类型
		//auto il = { 10, 20, 30 };
		//initializer_list<int> il = { 10, 20, 30 };
		//cout << typeid(il).name() << endl;
		//cout << sizeof(il) << endl;
	}
}

int main()
{
	Lzc::test_list1();
	Lzc::test_list2();
	Lzc::test_list3();
	Lzc::test_list4();
	return 0;
}

注意:声明和定义分离时,为什么定义时,是list<T>::iterator,不是iterator,因为iterator在list<T>中typedef了,就属于list<T>的成员变量了。