鏈表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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章