1. 程式人生 > >學習STL,實現一個單鏈表的迭代器

學習STL,實現一個單鏈表的迭代器

template<typename T>
LinkList<T>::LinkList()
{
	Node<T>* head = new Node<T>(0);
	first = head;
	head->next = NULL;
}

template<typename T>
LinkList<T>::~LinkList()
{
	Node<T>* delNode = NULL;
	while(first != NULL)
	{
		delNode = first;
		first = first->next;
		delete delNode;
	}
}

template <typename T>
void LinkList<T>::Insert(const T &data, int index)
{
	int count = 1;
	Node<T> *searchNode = first;

	while (count < index && searchNode->next != NULL)
	{
		++count;
		searchNode = searchNode->next;
	}

	// 插入連結串列
	Node<T> *newNode = new Node<T>(data);
	newNode->next = searchNode->next;
	searchNode->next = newNode;
}

//顯示連結串列中的所有資料(測試用)  
template <typename T>  
ostream &operator<<(ostream &os, const LinkList<T> &list)  
{  
	for (Node<T> *searchNode = list.first->next;  searchNode != NULL;  searchNode = searchNode->next)  
	{  
		os << searchNode -> data;  
		if (searchNode -> next != NULL) //尚未達到連結串列的結尾  
			cout << " -> ";  
	}  
	return os;  
} 

//ListIterator的實現
template <typename T>
const T& ListIterator<T>::operator*() const throw (std::out_of_range)
{
	if (IsEmpty())
		throw std::out_of_range("iterator is out of range");
	// 返回當前指標指向的內容
	return currentNode->data;
}
template <typename T>
T &ListIterator<T>::operator*() throw (std::out_of_range)
{
	//首先為*this新增const屬性,以呼叫該函式的const版本,
	//然後再使用const_case,將該函式呼叫所帶有的const屬性轉除
	//operator->()的non-const版本與此類同
	return
		const_cast<T &>(static_cast<const ListIterator<T> &>(*this).operator*());
}

template <typename T>
const Node<T> *ListIterator<T>::operator->() const throw (std::out_of_range)
{
	if (IsEmpty())
		throw std::out_of_range("iterator is out of range");
	//直接返回指標
	return currentNode;
}

template <typename T>
Node<T> *ListIterator<T>::operator->() throw (std::out_of_range)
{
	return const_cast<Node<T> *> (static_cast<const ListIterator<T> >(*this).operator->());
}

template <typename T>
ListIterator<T>& ListIterator<T>::operator++() throw (std::out_of_range)
{
	if (IsEmpty())
		throw std::out_of_range("iterator is out of range");
	//指標前移
	currentNode = currentNode->next;
	return *this;
}

template <typename T>
ListIterator<T>& ListIterator<T>::operator++(int) throw (std::out_of_range)
{
	ListIterator tmp(*this);
	++(*this); //呼叫前向++版本
	return tmp;
}

template<typename T>
ListIterator<T>& ListIterator<T>::operator=(const LinkList<T>& list) throw (std::out_of_range)
{
	this->list = list;
	this->currentNode = list.first->next;
	return *this;
}

template <typename T>
bool ListIterator<T>::IsEmpty() const
{
	if (currentNode == NULL)
		return true;
	return false;
}

4.測試程式碼

#include "link_list.h"
int _tmain(int argc, _TCHAR* argv[])
{
	LinkList<int> iMyList;
	for (int i = 0; i < 10; ++i)  
	{  
		iMyList.Insert(i+1, i+1);  
	}  
	cout << "Iterator:";
	for (ListIterator<int> iter(iMyList); !iter.IsEmpty(); ++iter)  
	{  
		cout << *iter << " ";  
	}  
	cout << endl;  

	cout << "Iterator2:";
	for (ListIterator<int> iter2 = iMyList; !iter2.IsEmpty();++iter2)
	{
		cout << *iter2 << " ";
	}
	cout << endl;  

	cout << "ostream:" << iMyList << endl;  

	ListIterator<int> iter(iMyList);  
	cout << "first = " << *iter << endl;  

	system("pause");
	return 0;
}
本示例直接貼上執行。 最後,雖然實現簡單,但是與STL中的迭代器是不能相提並論的,設計一個良好的迭代器不是一件簡單的事情,從STL的迭代器的設計中就可以看出。