前几天写一些简单的容器, 然后就顺便写了下迭代器。。。
不会画UML图。。就文字描述下好了。。。
虚类:Iterable (注意这里并不是Iterator)
派生出相关的子类, 如LinkListIterator,ArrayListIterator
并实现operator++,operator--, operator==接口;
相关容器并不直接返回其相关迭代器, 而是返回一个Iterator, 其也有相关的operator++, operator--, operator==方法, 调用这些方法时由Iterator类调用相关迭代器类对应的方法(好像是代理模式, 但Iterator并没有实现Iterable)
本来是想直接Iterable<Object> *it = Container<Object>.begin()这样的。。但这样没办法回收new出来的内存, 所以在外面加上Iterator类来释放相关内存, 不过这样也有不怎么好的地方如下面代码;
Container<Object> c;
...插入数据...
for(Iterator<Object> it = c.begin(); it != c.end(); ++it)
...
每次it跟c.end()进行比较的时候都会生成一个
Iterator对象, 感觉效率应该不咋滴=。=,,
下面附上迭代器相关代码:
Iterator.h
#ifndef __ITERATOR__
#define __ITERATOR__
#include "Iterable.h"
template<class RetType>
class Iterator
{
public:
Iterator(Iterable<RetType> *);
Iterator<RetType> &operator++();
Iterator<RetType> &operator--();
bool operator==(Iterator<RetType> &iter);
bool operator!=(Iterator<RetType> &iter);
RetType &operator*();
RetType &getValue();
~Iterator();
private:
Iterable<RetType> *_proxy;
};
template<class RetType> Iterator<RetType>::Iterator(Iterable<RetType> *ptr):_proxy(ptr)
{}
template<class RetType> Iterator<RetType> &Iterator<RetType>::operator++()
{
++*_proxy;
return *this;
}
template<class RetType> Iterator<RetType> &Iterator<RetType>::operator--()
{
--*_proxy;
return *this;
}
template<class RetType> bool Iterator<RetType>::operator==(Iterator<RetType> &iter)
{
return *_proxy == iter._proxy; //no problem here
}
template<class RetType> bool Iterator<RetType>::operator!=(Iterator<RetType> &iter)
{
return !(*this == iter);
}
template<class RetType> RetType &Iterator<RetType>::operator*()
{
return getValue();
}
template<class RetType> RetType &Iterator<RetType>::getValue()
{
return _proxy->getValue();
}
template<class RetType> Iterator<RetType>::~Iterator()
{
delete _proxy;
}
#endif
Iterable.h
#ifndef __ITERABLE__
#define __ITERABLE__
template<class RetType>
class Iterable
{
public:
virtual Iterable<RetType> &operator++() = 0;
virtual Iterable<RetType> &operator--() = 0;
virtual bool operator==(Iterable<RetType> *) = 0;
virtual bool operator!=(Iterable<RetType> *);
virtual RetType &getValue() = 0;
virtual ~Iterable() {};
};
template<class RetType> bool Iterable<RetType>::operator!=(Iterable<RetType> *iter)
{
return !(*this == iter);
}
#endif
继承了Iterable类的LinkListIterator类
#ifndef __LINKLISTITERATOR__
#define __LINKLISTITERATOR__
#include "Iterable.h"
template<class Object>
class LinkNode;
template<class RetType>
class LinkListIterator :public Iterable<RetType>
{
public:
LinkListIterator(LinkNode<RetType> *);
LinkListIterator<RetType> &operator++();
LinkListIterator<RetType> &operator--();
bool operator==(Iterable<RetType> *);
RetType &getValue();
private:
LinkNode<RetType> *_ptr;
};
template<class RetType> LinkListIterator<RetType>::LinkListIterator(LinkNode<RetType> *ptr):_ptr(ptr)
{}
template<class RetType> bool LinkListIterator<RetType>::operator==(Iterable<RetType> *iter)
{
return _ptr == dynamic_cast<LinkListIterator<RetType> *>(iter)->_ptr;
}
template<class RetType> LinkListIterator<RetType> &LinkListIterator<RetType>::operator++()
{
_ptr = _ptr->next;
return *this;
}
template<class RetType> LinkListIterator<RetType> &LinkListIterator<RetType>::operator--()
{
_ptr = _ptr->prev;
return *this;
}
template<class RetType> RetType &LinkListIterator<RetType>::getValue()
{
return _ptr->getValue();
}
#endif
//----------------------------------------------------------------------------------------
代码就上面那些了。。。
下面是一个用来测试的List类。。。。。。
Collection.h
#ifndef __COLLECTION__
#define __COLLECTION__
#include <typeinfo>
template<class Object>
class Collection
{
public:
Collection();
virtual bool insert(Object) = 0;
virtual bool remove(Object) = 0;
virtual bool search(Object) = 0;
virtual unsigned long size();
virtual void clear() {};
virtual ~Collection() {};
virtual const char *toString();
private:
unsigned long _size;
protected:
void __incSize();
void __decSize();
void __resize(unsigned long);
};
template<class Object> Collection<Object>::Collection():_size(0)
{}
template<class Object> unsigned long Collection<Object>::size()
{
return this->_size;
}
template<class Object> void Collection<Object>::__incSize()
{
++_size;
}
template<class Object> void Collection<Object>::__decSize()
{
--_size;
}
template<class Object> void Collection<Object>::__resize(unsigned long sz)
{
_size = sz;
}
template<class Object> const char *Collection<Object>::toString()
{
return typeid(*this).name();
}
#endif
继承Collection的List类
List.h
#ifndef __LIST__
#define __LIST__
#include "Collection.h"
#include "Iterator.h"
template<class Object>
class List :public Collection<Object>
{
public:
virtual Object popBack() = 0;
virtual Object popFront() = 0;
virtual bool insertFront(Object) = 0;
virtual bool insertBack(Object) = 0;
virtual Iterator<Object> begin() = 0;
virtual Iterator<Object> end() = 0;
virtual ~List() {};
};
#endif
继承List类的LinkList
LinkList.h
#ifndef __LINKLIST__
#define __LINKLIST__
#include "List.h"
#include "Iterator.h"
#include "LinkListIterator.h"
template<class Object>
class LinkNode
{
public:
LinkNode();
void setValue(Object);
Object &getValue();
LinkNode<Object> *next;
LinkNode<Object> *prev;
private:
Object _value;
};
template<class Object> LinkNode<Object>::LinkNode():next(NULL), prev(NULL)
{}
template<class Object> void LinkNode<Object>::setValue(Object value)
{
this->_value = value;
}
template<class Object> Object &LinkNode<Object>::getValue()
{
return this->_value;
}
template<class Object>
class LinkList :public List<Object>
{
public:
LinkList();
LinkList(LinkList<Object> &);
bool insert(Object); //by order
Object popBack();
Object popFront();
bool insertFront(Object);
bool insertBack(Object);
bool remove(Object);
bool search(Object);
void clear();
LinkList<Object> &operator = (LinkList<Object> &);
Object &front();
Object &back();
Iterator<Object> begin();
Iterator<Object> end();
~LinkList();
private:
LinkNode<Object> *_list;
LinkNode<Object> *_tail;
};
template<class Object> LinkList<Object>::LinkList() :_list(new LinkNode<Object>()), _tail(new LinkNode<Object>())
{
_list->next = _tail;
_tail->prev = _list;
}
template<class Object> LinkList<Object>::LinkList(LinkList<Object> &list) :_list(new LinkNode<Object>()), _tail(new LinkNode<Object>())
{
_list->next = _tail;
_tail->prev = _list;
*this = list;
}
template<class Object> bool LinkList<Object>::insert(Object value)
{
LinkNode<Object> *node = new LinkNode<Object>();
if (!node)
return false;
node->setValue(value);
LinkNode<Object> *tmp = _list->next;
while (tmp != _tail)
{
if (tmp->getValue() > value)
break;
tmp = tmp->next;
}
node->next = tmp;
node->prev = tmp->prev;
node->prev->next = node;
tmp->prev = node;
__incSize();
return true;
}
template<class Object> bool LinkList<Object>::insertFront(Object value)
{
LinkNode<Object> *tmp = new LinkNode<Object>();
if(!tmp)
return false;
tmp->setValue(value);
tmp->next = _list->next;
tmp->prev = _list;
tmp->next->prev = tmp;
_list->next = tmp;
__incSize();
return true;
}
template<class Object> bool LinkList<Object>::insertBack(Object value)
{
LinkNode<Object> *tmp = new LinkNode<Object>();
if(!tmp)
return false;
tmp->setValue(value);
tmp->next = _tail;
tmp->prev = _tail->prev;
tmp->prev->next = tmp;
_tail->prev = tmp;
__incSize();
return true;
}
template<class Object> Object LinkList<Object>::popBack()
{
if (size() == 0)
throw exception();
LinkNode<Object> *tmp = _tail->prev;
Object value = tmp->getValue();
delete _tail;
__decSize();
_tail = tmp;
_tail->next = NULL;
return value;
}
template<class Object> Object LinkList<Object>::popFront()
{
if (size() == 0)
throw exception();
LinkNode<Object> *tmp = _list->next->next;
Object value = _list->next->getValue();
delete _list->next;
__decSize();
_list->next = tmp;
tmp->prev = _list;
return value;
}
template<class Object> bool LinkList<Object>::remove(Object value)
{
LinkNode<Object> *tmp = _list->next;
LinkNode<Object> *tmp2 = NULL;
unsigned long sz = size();
while (tmp != _tail)
{
tmp2 = tmp->next;
if (tmp->getValue() == value)
{
tmp->prev->next = tmp->next;
tmp->next->prev = tmp->prev;
delete tmp; __decSize();
}
tmp = tmp2;
}
return bool(sz - size());
}
template<class Object> bool LinkList<Object>::search(Object value)
{
LinkNode<Object> *tmp = _list;
while(tmp)
{
if(tmp->getValue() == value)
return true;
tmp = tmp->next;
}
return false;
}
template<class Object> void LinkList<Object>::clear()
{
while(size() != 0)
popBack();
}
template<class Object> LinkList<Object> &LinkList<Object>::operator = (LinkList<Object> &list)
{
clear();
long sz = list.size();
LinkNode<Object> *head = list.front();
for (LinkNode<Object> *head = list.front(); head != list.back(); head = head->next)
insertBack(head->getValue());
return *this;
}
template<class Object> Object &LinkList<Object>::front()
{
return _list->next->getValue();
}
template<class Object> Object &LinkList<Object>::back()
{
return _tail->prev->getValue();
}
template<class Object> Iterator<Object> LinkList<Object>::begin()
{
return Iterator<Object>(new LinkListIterator<Object>(_list->next));
}
template<class Object> Iterator<Object> LinkList<Object>::end()
{
return Iterator<Object>(new LinkListIterator<Object>(_tail));
}
template<class Object> LinkList<Object>::~LinkList()
{
clear();
delete _list;
delete _tail;
_list = NULL;
_tail = NULL;
}
#endif
//------------------------------------------------------------------------------------------------------
测试代码:
#include <iostream>
#include "LinkList.h"
using namespace std;
int main()
{
List<int> * list = new LinkList<int>();
for(int i = 0; i < 10; ++i)
list->insert(10 - i);
for(Iterator<int> it = list->begin(); it != list->end(); ++it)
cout << *it << endl;
delete list;
return 0;
}
测试时的截图:(不要在意那个时间=。=, 并不准确的。。)
就写这么多吧。。。上面的代码写错的话,,麻烦指正下。。。