C++(17.5)——list模拟实现扩展

在上篇文章中,实现了list的大部分功能以及部分迭代器。本片文章将对剩下的功能进行补充。

1. const迭代器:

对于上篇文章中实现的迭代器只能使用于非const类型的对象。对于const类型的遍历,则需要额外编写const类型的迭代器。例如对于下面的场景:

void print_list(const list& s)
	{
		list::const_iterator it2 = s.begin();
		while (it2 != s.end())
		{
			cout << *it2;
			it2++;
		}
	}

对于const与非const类型的变量的区别,是const类型的对象不能修改。因此,实现const迭代器的第一种方法,便是将非const迭代器的相关代码进行复制然后进行改动,基于const类型本身的性质,只需要将operator*()函数的返回值类型改为const类型即可,对应代码如下:

template
	struct __list_const_iterator
	{
		typedef ListNode Node;
		typedef __list_const_iterator self;
		__list_const_iterator(Node* node)
			: _node(node)
		{}

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

		self& operator++(int)
		{
			self tmp(_node);
			_node = _node->_next;
			return tmp;
		}

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

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

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

		Node* _node;
	};

在完成上述步骤后,还需要在list中,引入__list_const_iterator,并且为了方便书写,利用typedef函数将其改写为const_iterator。将成员函数begin(),end()进行复制,然后改为const成员函数,代码如下:

const_iterator begin() const
		{
			return _phead->_next;
		}

		const_iterator end() const
		{
			return _phead;
		}

 此时,再运行上方给出的代码:

void print_list(const list& s)
	{
		list::const_iterator it2 = s.begin();
		while (it2 != s.end())
		{
			cout << *it2;
			it2++;
		}
	}
print_list(It);

 运行结果如下:

C++(17.5)——list模拟实现扩展_第1张图片

上述步骤虽然可以实现const迭代器的使用,但是两种迭代器的代码重复率过高。只有二者的成员函数operator*()的返回值类型不同,以及迭代器名称不同。为了简化上述代码,可以使用两个模板参数,即:

template
	struct __list_iterator
	{
		typedef ListNode Node;
		typedef __list_iterator self;
		__list_iterator(Node* node)
			: _node(node)
		{}

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

		self& operator++(int)
		{
			self tmp(_node);
			_node = _node->next;
			return tmp;
		}

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

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

		Node* _node;
	};

 其中,第二个模板参数Ref用于表示返回类型是const还是非const。并且,对list中引入的迭代器类型,通过传递不同的参数来进行区分,即:

template
	class list
	{
		typedef ListNode  Node;
	public:
		typedef __list_iterator iterator;
		typedef __list_iterator const_iterator;
		
		iterator begin()
		{
			return _phead->_next;
		}

		iterator end()
		{
			return _phead;
		}
		
		const_iterator begin() const
		{
			return _phead->_next;
		}

		const_iterator end() const
		{
			return _phead;
		}


		
		Node* _phead;
	};

2. 代码总览:
 

#include
#include
using namespace std;


namespace violent
{
	template
	struct ListNode
	{
		ListNode(const T& x = T())
			: _prev(nullptr)
			, _next(nullptr)
			, _data(x)
		{}
		
		ListNode* _prev;
		ListNode* _next;
		T _data;
	};

	template
	struct __list_iterator
	{
		typedef ListNode Node;
		typedef __list_iterator self;
		__list_iterator(Node* node)
			: _node(node)
		{}

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

		self& operator++(int)
		{
			self tmp(_node);
			_node = _node->_next;
			return tmp;
		}

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

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

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


	/*template
	struct __list_const_iterator
	{
		typedef ListNode Node;
		typedef __list_const_iterator self;
		__list_const_iterator(Node* node)
			: _node(node)
		{}

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

		self& operator++(int)
		{
			self tmp(_node);
			_node = _node->_next;
			return tmp;
		}

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

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

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

		Node* _node;
	};*/

	template
	class list
	{
		typedef ListNode  Node;
	public:
		typedef __list_iterator iterator;
		typedef __list_iterator const_iterator;
		list()
		{
			_phead = new Node;
			_phead->_next = _phead;
			_phead->_prev = _phead;
		}

		void empty()
		{
			_phead = new Node;
			_phead->_next = _phead;
			_phead->_prev = _phead;
		}

		list(const list& s)
		{
			empty();
			for (auto e : s)
			{
				push_back(e);
			}
		}

		void swap(list& s)
		{
			std::swap(_phead, s._phead);
		}

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

		iterator begin()
		{
			return _phead->_next;
		}

		iterator end()
		{
			return _phead;
		}
		
		const_iterator begin() const
		{
			return _phead->_next;
		}

		const_iterator end() const
		{
			return _phead;
		}


		/*void push_back(const T& x)
		{
			Node* newnode = new Node(x);
			Node* tail = _phead->_prev;
			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _phead;
			_phead->_prev = newnode;
		}*/

		void push_back(const T& x)
		{
			insert(_phead, x);
		}

		void push_front(const T& x)
		{
			insert(_phead->_next, x);
		}

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

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

		void pop_back()
		{
			erase(_phead->_prev);
		}

		void pop_front()
		{
			erase(_phead->_next);
		}

		iterator erase(iterator pos)
		{
			assert(pos != end());
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

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

			delete cur;
			return next;
		}

		void clear()
		{
			iterator i2 = begin();
			while (i2 != end())
			{
				i2 = erase(i2);
			}
		}


		~list()
		{
			clear();

			delete _phead;
			_phead = nullptr;
		}
		Node* _phead;
	};

	void print_list(const list& s)
	{
		list::const_iterator it2 = s.begin();
		while (it2 != s.end())
		{
			cout << *it2;
			it2++;
		}
	}

	

	void test1()
	{
		list It;
		It.push_back(1);
		It.push_back(2);
		It.push_back(3);
		It.push_back(4);
		list::iterator it1 = It.begin();
		while (it1 != It.end())
		{
			cout << *it1 << ' ';
			++it1;
		}
		cout << endl;
		It.insert(It.begin(), 5);
		It.insert(It.begin(), 6);
		It.insert(It.begin(), 7);
		It.insert(It.begin(), 8);
		It.push_front(9);
		It.push_front(9);
		It.push_front(9);
		
		for (auto e : It)
		{
			cout << e << ' ';
		}

		cout << endl;
		It.pop_back();
		It.pop_back();
		It.pop_front();
		It.pop_front();
		for (auto e : It)
		{
			cout << e << ' ';
		}

		cout << endl;
		cout << "const迭代器:";
		print_list(It);

	

	}
	struct AA
	{
		AA(int aa1 = 1, int aa2 = 2)
			: _aa1(aa1)
			, _aa2(aa2)
		{}

		int _aa1;
		int _aa2;
	};

	void test3()
	{
		AA a(2, 3);
		list It;

		It.push_back(a);
		It.push_back(AA());
		It.push_back(AA(1, 2));

		list::iterator it = It.begin();
		while (it != It.end())
		{
			cout << it->_aa1 << endl;
			it++;
		}
	}
}

#include"list_1.h"

int main()
{
	violent::test3();
	return 0;
}

你可能感兴趣的:(C++,c++,开发语言)