链表List的代码,但是缺少保护

template <typename Object>        //这里的实现是不改变data的
class List
{
private:
	struct Node              //struct是public的,这里把它作为private,也没毛病,就是Node里的东西List类都能用
	{
		Object data;
		Node *prev;
		Node *next;
		Node(const Object &d = Object(), Node *p = NULL, Node *n = NULL) :data(d), prev(p), next(n){}  //这种构造办法很好,不容易出错,建议用	
	};
public:
	class const_iterator
	{
	public:
		const_iterator() :current(NULL)
		{}
		const Object & operator* () const         //*的运算符重载,取数据的,protect里有retrieve
		{
			return retrieve();
		}
		const_iterator & operator++()             //前缀的++(++i),使用空参数列表。前缀比后缀快,所以编程的时候尽量用++i......
		{
			current = current->next;
			return *this;
		}

		const_iterator operator++ (int)           //后缀的++(i++),给后缀指定一个匿名的int参数,int参数是不会使用的,只是一个不同的标识
		{
			const_ierator old = *this;
			++(*this);
			return old;
		}

		bool operator== (const const_iterator &rhs) const
		{
			return current == rhs.current;
		}
		bool operator!=(const const_iterator &rhs) const
		{
			return !(*this == rhs);
		}
	protected:
		Node *current;                         //current是指向Node的指针,不能是私有的,否则iterator将不能访问这个指针。protect允许继承的类具有访问这些成员的权限,但是不允许其他的类访问
		Object & retrieve() const
		{
			return current->data;
		}
		const_iterator(Node *p) :current(p){}          //不希望所有的类都能访问这个const_iterator的构造函数,但是希望iterator可以访问,所以放到了protect里
		friend class List < Object > ;
	};
	class iterator:public const_iterator      //两个迭代器类型,用了继承。
	{
	public:
		iterator(){}
		Object & operator*()    //*可以修改的重载
		{
			return retrieve();
		}
		const Object & operator* () const    //*只能访问的重载,不能改变,简单使用了与const_iterator完全相同的实现
		{
			return const_iterator::operator*();           //在iterator中,修改函数必须显示实现,因为不这样的话原始的实现就会被新加的修改函数隐藏
		}
		iterator & operator++ ()                   //这里operator==和operator!=不需要改变,但是++要改变,因为类型改变了,这个新的实现隐藏了const_iterator的原始实现
		{
			current = current->next;           
			return *this;
		}

		iterator operator++ (int)
		{
			iterator old = *this;
			++(*this);
			return old;
		}
	protected:
		iterator(Node *p) :const_iterator(p)
		{}

		friend class List < Object > ;

	};
public:
	List()                                   //喜闻乐见,List的构造函数,拷贝构造函数,析构函数,=的运算符重载
	{
		init();
	}
	List(const List & rhs)
	{
		init();
		*this = ths;
	}
	~List()
	{
		clear();
		delete head;
		delete tail;
	}
	const List & operator=(const List &rhs)
	{
		if (this == &rhs)
			return *this;
		clear();
		for (const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr)
			push_back(*itr);
		return *this;
	}

	//一些常用小函数
	iterator begin()                                 //迭代器的取begin和end,这里又一次说明,begin是真的begin,end是最后一个的后一个
	{
		return iterator(head->next);                //这个iterator()是迭代器iterator的构造函数,return构造函数,是因为构造函数临时构造了一个对象,然后临时返回这个对象,所以出现了这里的return
	}
    const_iterator begin() const
	{
		return const_iterator(head->next);
	}

	iterator end()
	{
		return iterator(tail);
	}

	const_iterator end() const
	{
		return const_iterator(tail);
	}

	int size() const                              //取大小
	{
		return theSize;
	}

	bool empty() const                          //判空
	{
		return size() == 0;
	}

	void clear()                                   //清空,调用pop_front让clear不染指节点空间的回收
	{
		while (!empty())
			pop_front();
	}

	Object & front()                           //取首元素,这个*iterator在迭代器的类里,*是重载过的,意思就是取data
	{
		return *begin();
	}

	const Object & front() const            //每个有两种,带const的是不能修改的,不带const的是能修改的
	{
		return *begin();
	}

	Object & back()                           //取尾元素
	{
		return *--end();
	}

	const Object & back() const
	{
		return *--end();
	}

	void push_front(const Object &x)
	{
		insert(end(), x);
	}
	void push_back(const Object &x)
	{
		insert(end(), x);
	}
	void pop_front()
	{
		erase(begin());
	}
	void pop_back()
	{
		erase(--end());                 //这样也是避免结点空间回收的,只有几个是涉及到节点空间的
	}

	iterator insert(iterator itr, const Object &x)
	{
		Node *p = itr.current;          //让*p是指向当前结点的指针     
		theSize++;
		return iterator(p->prev = p->prev->next = new Node(x, p->prev, p));
		/*这个拆开看,最后iterator()里的东西,就是这个new的Node,数据是x的这个。双向链表的插入节点
		Node *newNode = new Node(x,p->prev,p);
		p->prev->next=newNode;
		p->prev=newNode;
		*/

	}

	iterator erase(iterator itr)       //删除一个的
	{
		Node *p = itr.current;
		iterator retVal(p->next);       //erase返回指向删除结点的下一个结点的指针,这行的作用
		p->prev->next = p->next;
		p->next->prev = p->prev;
		delete p;
		theSize--;
		return retVal;
	}

	iterator erase(iterator start, iterator end)    //这个是都删除的
	{
		for (iterator itr = from; itr != to;)       //这个感觉给错了,from和to应该用start和end
			itr = erase(itr);
		return to;
	}

	private:
		int theSize;
		Node *head;
		Node *tail;
		void init()
		{
			theSize = 0;
			head = new Node;
			tail = new Node;
			head->next = tail;
			tail->prev = head;
		}
};

发布了56 篇原创文章 · 获赞 9 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章