1. 程式人生 > >用C++實現STL容器list

用C++實現STL容器list

#ifndef LIST_H_
#define LIST_H_

//#include "Node.h"
//#include "const_iterator.h"

template<class Object>
class List
{
private:
	struct Node 
	{
		Object data;
		Node *prev;
		Node *next;
		Node(const Object & obj = Object(), Node * p = NULL, Node * n = NULL):data(obj), prev(p), next(n) {}	
	};
public:
	class const_iterator
	{
	public:
		const_iterator():current(NULL){}

		const Object & operator*() const{
			return retrieve();
		}
		const_iterator & operator++(){
			current = current->next;
			return *this;
		}
		const_iterator & operator--(){
			current = current->prev;
			return *this;
		}
	/*	const_iterator operator--(int){
			const_iterator old = *this;
			--(*this);
			return old;
		}*/

	/*	const_iterator operator++(int) {
			const_iterator 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;
		Object & retrieve() const{
			return current->data;
		}
		const_iterator(Node *p):current(p){}
		friend class List<Object>;
	};

	class iterator:public const_iterator
	{
	public:
		iterator() {}

		Object & operator*() {
			return retrieve();
		}

		const Object & operator*() const{
			return const_iterator::operator*();
		}

		iterator & operator++(){
			current = current->next;
			return *this;
		}
		iterator & operator--(){
			current = current->prev;
			return *this;
		}
		/*	iterator operator--(int){
		iterator old = *this;
		--(*this);
		return old;
		}*/
	/*	iterator operator++(int){
			iterator old = *this;
			++(*this);
			return old;
		}*/

	protected:
		iterator(Node *p):const_iterator(p){}
		friend class List<Object>;
	};

public:
	List(){init();}

	List(const List & rhs){
		init();
		*this = rhs;
	}

	~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(){
		return iterator(head->next);
	}
	
	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(){
		while(!empty()){
			pop_front();
		}
	}

	Object & front(){
		return *begin();
	}

	const Object & front() const{
		return *begin();
	}


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

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

	void push_front(const Object & obj){
		insert(begin(), obj);
	}

	void push_back(const Object & obj){
		insert(end(), obj);
	}
	
	void pop_front(){
		erase(begin());
	}
	
	void pop_back(){
		erase(--end());
	}

	iterator insert(iterator itr, const Object & obj){
		Node *p = itr.current;
		theSize++;
		return iterator(p->prev = p->prev->next = new Node(obj, p->prev, p));
	}

	iterator erase(iterator itr){
		Node * p = itr.current;
		iterator retVal(p->next);
		p->prev->next = p->next;
		p->next->prev = p->prev;

		delete p;
		theSize--;

		return retVal;
	}

	iterator erase(iterator start, iterator end){
		for (iterator it = start; it != end; ){
			it = erase(it);
		}
		return end;
	}

private:
	int theSize;
	Node *head;
	Node *tail;

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

#endif
#include <iostream>
#include "List.h"

using namespace std;

template<class Container>
void print(Container & ct)
{
	for (auto it = ct.begin(); it != ct.end(); it++)
		cout << *it << " ";
	cout << endl;
}

int main()
{
	List<int> l;
	l.push_back(1);
	l.push_back(2);
	l.push_back(3);
	l.push_back(4);

	cout << "L: ";
	print(l);
	cout << "list's size is " << l.size() << endl;
	
	l.push_front(0);
	l.push_front(-1);
	l.push_front(-2);

	cout << "L: ";
	print(l);
	cout << "list's size is " << l.size() << endl;

	cout << "l.front() is " << l.front() << endl;
	cout << "l.back() is " << l.back() << endl;

	l.pop_back();
	cout << "After pop_back(): ";
	print(l);

	l.pop_front();
	cout << "After pop_front(): ";
	print(l);

	l.insert(++l.begin(), 100);
	cout << "After insert 100 at the ++list.begin(): ";
	print(l);

	l.erase(++l.begin(), --l.end());
	cout << "After the erase(++l.begin(), --l.end()): ";
	print(l);


	system("pause");
	exit(0);
}