Iterator Patterns: 迭代器的封装一定离不开容器,但是自己写容器不仅仅给STL的容器套个壳,就需要用到双重指针来存储源数据

Intent

Provide a way to access the elements of an aggregate object sequentially without
exposing its underlying representation.

Iterator Patterns: 迭代器的封装一定离不开容器,但是自己写容器不仅仅给STL的容器套个壳,就需要用到双重指针来存储源数据_第1张图片
Iterator Patterns: 迭代器的封装一定离不开容器,但是自己写容器不仅仅给STL的容器套个壳,就需要用到双重指针来存储源数据_第2张图片
Iterator Patterns: 迭代器的封装一定离不开容器,但是自己写容器不仅仅给STL的容器套个壳,就需要用到双重指针来存储源数据_第3张图片

// refactoringtopattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include 
#include 
#include 

#define DEFAULT_LIST_CAPACITY 1024

template<class Item>
class Iterator {
public:
    virtual void First() = 0;
    virtual void Next() = 0;
    virtual bool IsDone() const = 0;
    virtual Item CurrentItem() const = 0;
protected:
    Iterator() {
        std::cout << __FUNCTION__ << std::endl;
    }
};

template<class Item>
class IteratorPtr {
public:
    IteratorPtr(Iterator<Item>* i) :i_(i) {}
    ~IteratorPtr() {
        delete i_;
    }
    Iterator<Item>* operator->() {
        return i_;
    }
    Iterator<Item>& operator*() {
        return *i_;
    }
private:
    // multiple deletions of i_
    IteratorPtr(const IteratorPtr&) {}
    IteratorPtr& operator=(const IteratorPtr& a) {
        return (*this);
    }

private:
    Iterator<Item>* i_;
};

// 抽象接口
template<class Item>
class AbstractList {
public:
    AbstractList() {}
    virtual Iterator<Item>* CreateIterator() const = 0;
};

template<typename Item>
class ListIterator;

// 实现接口
template<class Item>
class List : public AbstractList<Item>{
public:
    List(long size = DEFAULT_LIST_CAPACITY) {
        Item** new_item = new Item * [size];
        for (int i = 0; i < size; i++)
        {
            new_item[i] = new Item();
        }
        item_ = new_item;
        item_count_ = size;
    }
    long Count() const {
        return item_count_;
    }
    Item& Get(long index) const {
		return  *(*(item_ + index));
    }
    virtual Iterator<Item>* CreateIterator() const {
        return new ListIterator<Item>(this);
    }
private:
    Item** item_;
    long item_count_;
};

class IteratorOutOfBounds : public std::exception {
public:
    const char* what() const throw() {
        return "son of bitch!";
    }
};

template<class Item>
class ListIterator : public Iterator<Item> {
public:
    ListIterator(const List<Item>* aList) :Iterator<Item>(),list_(aList), current_(static_cast<long>(0)) {
    }
    virtual void First() {
        current_ = 0;
    }
    virtual void Next() {
        current_++;
    }
    virtual bool IsDone() const {
        return current_ >= list_->Count();
    }
    virtual Item CurrentItem() const {
        // c++ primer : exception
        if (IsDone()) {
            throw IteratorOutOfBounds();
        }
        return list_->Get(current_);
    }
private:
    const List<Item>* list_;
    long current_;
};


template<class Item>
class ListTraverser {
public:
	ListTraverser(List<Item>* aList) :iterator_(aList) {}
	bool Traverse() {
		bool result = false;
		for (iterator_.First(); !iterator_.IsDone(); iterator_.Next()) {
			result = ProcessItem(iterator_.CurrentItem());
			if (result == false)
				break;
		}
		return result;
	}
protected:
    virtual bool ProcessItem(const Item&) = 0;
private:
    ListIterator<Item> iterator_;
};

class Employee {
public:
    Employee() {}
    ~Employee() {}
    void Print() {
        std::cout << __FUNCTION__ << std::endl;
    }
};

class PrintNEmployees : public ListTraverser<Employee*> {
public:
	PrintNEmployees(List<Employee*>* aList, int n) :
		ListTraverser<Employee*>(aList),
		total_(n), count_(0) {}
protected:
	bool ProcessItem(Employee* const& e) {
		count_++;
		e->Print();
		return count_ < total_;
	}
private:
	int total_;
	int count_;
};


template<class Item>
class FilteringListTraverser {
public:
    FilteringListTraverser(List<Item>* aList) :iterator_(aList){}
	bool Traverse() {
		bool result = false;

		for (iterator_.First(); !iterator_.IsDone(); iterator_.Next()) {
			if (TestItem(iterator_.CurrentItem()))
			{
				result = ProcessItem(iterator_.CurrentItem());
				if (result == false)
					break;
			}
		}
		return result;
	}
protected:
	virtual bool ProcessItem(const Item&) = 0;
	virtual bool TestItem(const Item&) = 0;
private:
	ListIterator<Item> iterator_;
};


void PrintEmployees(Iterator<Employee*>& i) {
    for (i.First(); !i.IsDone(); i.Next()) {
        i.CurrentItem()->Print();
    }
}

int main()
{
    {
        AbstractList<Employee*>* employees = new List<Employee*>(9);
        IteratorPtr<Employee*> iterator(employees->CreateIterator());
        PrintEmployees(*iterator);
    }

    {
        List<Employee*>* employees = new List<Employee*>(10);
        PrintNEmployees pa(employees, 10);
        pa.Traverse();
    }

	{ // prints the first 10 employees
        List<Employee*>* employees = new List<Employee*>(5);
		ListIterator<Employee*> i(employees);
		int count = 0;
		for (i.First(); !i.IsDone(); i.Next()) {
			count++;
			i.CurrentItem()->Print();
			if (count >= 3)
				break;
		}
	}


}


Iterator Patterns: 迭代器的封装一定离不开容器,但是自己写容器不仅仅给STL的容器套个壳,就需要用到双重指针来存储源数据_第4张图片

你可能感兴趣的:(设计模式GoF,迭代器模式,c++)