stl中的list模拟实现

本文详细介绍了C++STL中的list容器,包括list的基本概念、节点的实现、迭代器的模拟实现(重点讲解了iterator和const_iterator的区别及合并),以及list类的代码实现,涉及构造函数、操作符重载和常用方法如push_back、pop_front等。
摘要由CSDN通过智能技术生成

一、list的简单介绍

首先我们要清楚list是一个带头双向循环的链表。

二、写出节点的代码

在下面代码中我们用到了模板,并且用的是struct没有用class,这是因为我们使用struct时相当于这一个类是公开的,当然我们也可以使用class但是得使用友元函数比较麻烦。

	template<class T>//这里用到了模板
	struct listnode
	{
		T _data;
		listnode* _next;
		listnode* _prev;
		listnode(const T& x = T())//这里使用的是匿名函数,因为不确定x是什么类型,所以给了一个匿名函数的全缺省
			:_data(x)
			, _next(nullptr)
			, _prev(nullptr)
		{}

	};

三、模拟实现迭代器(重点)

1、list中的迭代器是怎么实现的

我们可以查看stl的源码进行查看,如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看出list的迭代器就是由链表的一个节点指针来进行控制的,然后再进行对符号的重载

2、编写iterator类的代码

根据上述可编写以下代码:

template<class T>
	struct list_iterator
	{
		typedef listnode<T> Node;
		typedef list_iterator<T> 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 temp(*this);
			_node = _node->_next;
			return temp;
		}
		self operator--(int) {
			self temp(*this);
			_node = _node->_prev;
			return temp;
		}
		 T* operator->() {
			return &_node->_data;
		}
		 T& operator*() {
			return _node->_data;
		}
		bool operator!=(const self& s) {
			return s._node != _node;
		}
		bool operator==(const self& s) {
			return s._node == _node;
		}

3、对const_iterator进行理解

首先我们要清楚是对谁加const,是对迭代器本身加const还是对迭代器指向的内容加const,我们平常使用const_iteratot时我们可以对迭代器进行++或–,但是不可以对迭代器指向的内容进行修改,由此可以看出我们的const_iterator和iterator是两个类不可以直接对iterator加const

4、编写const_iterator类的代码

template<class T>
	struct list_const_iterator
	{
		typedef listnode<T> Node;
		typedef list_const_iterator<T> 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 temp(*this);
			_node = _node->_next;
			return temp;
		}
		self operator--(int) {
			self temp(*this);
			_node = _node->_prev;
			return temp;
		}
		const T* operator->() {
			return &_node->_data;
		}
		const T& operator*() {
			return _node->_data;
		}
		bool operator!=(const self& s) {
			return s._node != _node;
		}
		bool operator==(const self& s) {
			return s._node == _node;
		}
	};

5、对iterator类和const_iterator类进行合并

在编写iterator类和const_iterator类我们发现除了下面的代码不一样其余的代码都是一样的。
在这里插入图片描述
在这里插入图片描述
但是这样写的话,代码就会冗余,所以这时我们用一个类模板,对代码进行修改,如下:

template<class T,class Ref,class Ptr>
	struct list_iterator
	{
		typedef listnode<T> Node;
		typedef list_iterator<T,Ref,Ptr> 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 temp(*this);
			_node = _node->_next;
			return temp;
		}
		self operator--(int) {
			self temp(*this);
			_node = _node->_prev;
			return temp;
		}
		Ptr operator->() {
			return &_node->_data;
		}
		Ref operator*() {
			return _node->_data;
		}
		bool operator!=(const self& s) {
			return s._node != _node;
		}
		bool operator==(const self& s) {
			return s._node == _node;
		}
	};

四、list类进行代码实现

这里主要是写构造函数、拷贝构造、赋值拷贝、析构函数、迭代器的begin()和end()的实现,以及其他功能的实现。
代码如下:

template<class T>
	class list {
		typedef listnode<T> Node;
	public:
		typedef list_iterator<T,T&,T*> iterator;
		typedef list_iterator<T,const T&,const T*> const_iterator;
		void empty_init() {
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			_size = 0;
		}
		const_iterator begin() const{
			return _head->_next;
		}
		const_iterator end() const{
			return _head;
		}
		iterator begin() {
			return _head->_next;
		}
		iterator end() {//返回的是最后一个节点的后一个,所以返回的是头节点
			return _head;
		}
		list() {
			empty_init();
		}
		list(list<T>& it) {
			empty_init();
			for (auto e : it) {
				push_back(e);
			}
		}
		void swap(list<T>& It) {
			std::swap(_head, It->_head);
			std::swap(_size, It->_size);
		}
		list<T>& operator=(list<T>& It)
		{
			swap(It);
			return *this;
		}
		~list()
		{
			clear();
			delete(_head);
			_size = 0;
		}
		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());
		}
		void clear() {
			while (!empty()) {
				pop_back();
			}
		}
		bool empty() {
			return _size == 0;
		}
		size_t size() {
			return _size;
		}
		iterator erase(iterator pos) {
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;
			prev->_next = next;
			next->_prev = prev;
			delete cur;
			--_size;
			return iterator(next);
		}
		iterator insert(iterator pos, T x) {
			Node* cur = pos._node;
			Node* newNode = new Node(x);
			Node* prev = cur->_prev;
			prev->_next = newNode;
			newNode->_prev = prev;
			newNode->_next = cur;
			cur->_prev = newNode;
			
			++_size;
			return iterator(newNode);
		}
	private:
		Node* _head;
		size_t _size;
	};
  • 54
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 36
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值