C++(超级容易)通用链表类似Java集合类接口

C++(超级简单)通用链表类似Java集合类接口
之前写的那个重载的是全局的operator==,operator!= 操作符,实际意义上不是一个通用的做法,改成了重载成员的 operator==,operator!=
////////////////////////////////////////////////////////////////////////////////
//			简单的链表C++实现
// Aothor:	殷洪
// Date:	2006-06-18
// QQ:		47406310
// Email:	47406310@qq.com
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <stdexcept>
#include <string>

using namespace std;

template <class T> class Node {
public:
	Node() {
#ifdef _DEBUG
		cout << "Node()" << endl;
#endif
	}
	~Node() {
#ifdef _DEBUG
		cout << "~Node()" << endl;
#endif
	}
	T		data;
	Node*	next;
};


template <class T> class Iterator {
public:
	Iterator() : m_head(0)
		, m_curr(0) {}
	Iterator(Node<T>* node) : m_head(node)
		, m_curr(node) {
#ifdef _DEBUG
		cout << "Iterator()" << endl;
#endif
	}
	
	~Iterator() {
#ifdef _DEBUG
		cout << "~Iterator()" << endl;
#endif
	}
	
	bool hasElement() const {
		if (!m_curr) {
			return false;
		}
		return true;
	}
	
	const T& nextElement() {
		T& data = m_curr->data;
		m_curr = m_curr->next;
		return data;
	}
private:
	Node<T>* m_head;
	Node<T>* m_curr;
};

template <class T> class Link {
public:	

	Link();
	~Link();
	void add(const T&);
	void remove(const T&);
	bool find(const T&);
  void clear();
	inline bool empty() const { return m_head ? true : false; }
	inline Iterator<T> getIterator() const { return Iterator<T>(m_head); }

protected:
	void destory();

private:
	Node<T>* m_head;
	Node<T>* m_curr;
};


template <class T>
Link<T>::Link() : 
	m_head(0)
	, m_curr(0) {
#ifdef _DEBUG
	cout << "Link<T>::Link()" << endl;
#endif
}

template <class T>
Link<T>::~Link() {
	destory();
#ifdef _DEBUG
	cout << "Link<T>::~Link()" << endl;
#endif
}

template <class T>
void Link<T>::add(const T& element) {
	if (!(m_head && m_curr)) {
		m_head = new Node<T>;
		if (!m_head)
			throw std::bad_alloc("can't allocate memory!");

		m_head->data = element;
		m_head->next = 0;
		m_curr = m_head;

	} else {

		Node<T>* node = new Node<T>;
		if (!node)
			throw std::bad_alloc("can't allocate memory!");

		node->data = element;
		node->next = 0;

		if (m_curr && (0 == m_curr->next)) {
			m_curr->next = node;
			m_curr = node;
		}
	}
}

template <class T>
void Link<T>::destory() {
	while (m_head) {
		Node<T>* next = m_head->next;
		delete m_head;
		m_head = next;
	}
}

template <class T>
void Link<T>::remove(const T& element) {
	
	Node<T>* prev = 0;
	Node<T>* ptr = 0;

	ptr = m_head;
	while (ptr) {
		if (m_head->data == element) {
			Node<T>* next = m_head->next;
			delete m_head;
			m_head = next;
			break;
		}		

		prev = ptr;
		ptr = ptr->next;

		if (ptr->data == element) {
			prev->next = ptr->next;
			delete ptr;
			break;
		}
	}
}

template <class T>
bool Link<T>::find(const T& element) {

	Iterator<T> iter = getIterator();
	while (iter.hasElement()) {
		if (iter.nextElement() == element) {
			return true;
		}
	}
	return false;
}

template <class T>
void Link<T>::clear()
{
  Iterator<T> iter = getIterator();
  while (iter.hasElement()) {
    remove(iter.nextElement());
  }
}


class Student {
public:
  int id;
  std::string name;
  std::string sex;
  std::string remark;

  inline bool operator==(const Student& student) const {
    return this->id == student.id && this->name == student.name &&
      this->sex == student.sex && this->remark == student.remark;
  }

  inline bool operator!=(const Student& student) const {
    return !(*this == student);
  }

  friend inline ostream& operator<<(ostream& os, const Student& student) {
    cout << "-----------class Student-----------" << endl
         << "id: " <<     student.id <<endl
         << "name: " <<   student.name << endl
         << "sex: " <<    student.sex << endl
         << "remark: " << student.remark << endl;
    return os;
  }
};

typedef struct Message {
  Message() {}
  Message(const std::string& msg) : msg(msg), len(msg.length()) {}
  std::string msg;
  size_t len;

  inline bool operator==(const Message& msg) const {
    return this->len == msg.len && this->msg == msg.msg;
  }

  inline bool operator!=(const Message& msg) const {
    return !(*this == msg);
  }

  friend inline ostream& operator<<(ostream& os, const Message& msg) {
    cout << "-----------struct Message-----------" << endl
         << "msg: " << msg.msg << endl
         << "len: " << msg.len << endl;
    return os;
  }
} _message_t;

template<typename T>
void printElements(Link<T>& link)
{
	Iterator<T>& iter = link.getIterator();
	while (iter.hasElement()) {
		cout << iter.nextElement();
	}
}

void test_student() 
{
	Link<Student> students;
	Student st1;
	Student target;

	ostringstream oss;
	for (int i=0; i<1000; i++) {
		st1.id = i;
    oss.str("");
    oss << "name-" << i;
		st1.name = oss.str();
		
		if (i % 2) {
			st1.sex = "男";
		} else {
			st1.sex = "女";
		}

    oss.str("");
    oss << "remark-just soso-" << i;
		st1.remark = oss.str();
		students.add(st1);
		if (12 == i) {
			target = st1;
		}
	}

	cout << "all element: " << endl;
	printElements(students);

	Iterator<Student>& rmvIter = students.getIterator();
	int id = 0;
	while (rmvIter.hasElement()) {
		const Student& rmvElement = rmvIter.nextElement();
		if (4 == rmvElement.id) {
			students.remove(rmvElement);
		}
		/*
		//delete all elements
		if (id == rmvElement.id) {
			students.remove(rmvElement);
		}
		id++;
		*/
	}

	cout.setf(ios_base::boolalpha);
	cout << "is empty: "	<< students.empty() << endl;
	cout << "find(xxx): " << students.find(target) << endl;

	cout << "remove after:" << endl;
	printElements(students);
}

void test_stdstring()
{
  Link<std::string> strs;

  strs.add("Hello");
  strs.add("long");
  strs.add("time");
  strs.add("see");
  strs.add("!!!");

  cout << "strs.empty() = " << strs.empty() << endl;
  cout << "strs.find(\"!!!\") = " << strs.find("!!!") << endl;
  strs.remove("!!!");

  Iterator<std::string> strIter = strs.getIterator();
  while (strIter.hasElement()) {
    cout << strIter.nextElement() << ", ";
  }
  cout << endl;
}

void test_message()
{
  Link<Message> msgs;
  msgs.add(Message("Just"));
  msgs.add(Message("do"));
  msgs.add(Message("it"));
  msgs.add(Message("!!!"));

  cout << "test_message, find: " <<  msgs.find(Message("do")) << endl;
  printElements(msgs);

  msgs.remove(Message("!!!"));
  cout << "Message(\"!!!\") removed" << endl;
  printElements(msgs);

  cout << "Clean all elements" << endl;
  msgs.clear();
  printElements(msgs);
}
int main(int argc, char* argv[])
{
  test_student();
  test_stdstring();
  test_message();
	return 0;
}