一个简单迭代器的实现。。

这篇博客介绍了如何在C++中实现一个简单的迭代器,包括定义虚类Iterable作为基类,派生出LinkListIterator和ArrayListIterator等子类,并实现了operator++、operator--和operator==等接口。博客中提到,迭代器作为一个代理,调用相关容器的迭代器方法,同时为了解决内存回收问题,使用了一个额外的Iterator类来管理内存,但也带来了使用上的不便。
摘要由CSDN通过智能技术生成

尴尬前几天写一些简单的容器, 然后就顺便写了下迭代器。。。


不会画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


LinkListIterator.h
继承了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

继承CollectionList

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;
}

测试时的截图:(不要在意那个时间=。=, 并不准确的。。)


就写这么多吧。。。上面的代码写错的话,,麻烦指正下。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值