14.1.解釋
概念:提供一種方法順序訪問一個聚合對象中各個元素,而又不需暴露該對象的內部表示。
main(),客戶
IProject,產品接口
CProject,產品類
IIterator,迭代器接口
IProjectIterator,產品迭代器接口
CProjectIterator,產品迭代器實現類
說明:CProject實現產品類,能夠返回一個迭代器的指針。這個迭代器將封裝產品類裏的一個數組。所以迭代器在運行Next函數時,可以遍歷這個數組的所有元素。
簡單來說,就是用代碼實現vector<int>::iterator或vector<int>::const_iterator。
我們來看代碼:
//IProject.h
#pragma once
#include "IProjectIterator.h"
#include <iostream>
using std::string;
class IProject
{
public:
IProject(void)
{
}
virtual ~IProject(void)
{
}
virtual void Add(string name, int num, int cost) = 0;
virtual string GetProjectInfo() = 0;
virtual IProjectIterator* GetIterator() = 0;
virtual void Erase() = 0;
};
//Project.h
#pragma once
#include "iproject.h"
#include "IProjectIterator.h"
#include <iostream>
#include <vector>
using std::string;
using std::vector;
class CProject :
public IProject
{
public:
CProject(void);
CProject(string name, int num, int cost);
~CProject(void);
string GetProjectInfo();
void Add(string name, int num, int cost);
IProjectIterator * GetIterator();
void Erase();
private:
string m_name;
int m_num;
int m_cost;
vector<IProject*> m_projectList;
};
//Project.cpp
#include "StdAfx.h"
#include "Project.h"
#include "..\CommonDeclare\Convert.h"
#include "ProjectIterator.h"
#include <iostream>
#include <vector>
using std::string;
using std::vector;
CProject::CProject( void )
{
m_name = "";
m_num = 0;
m_cost = 0;
}
CProject::CProject(string name, int num, int cost) :m_name(name), m_num(num), m_cost(cost)
{
}
CProject::~CProject(void)
{
}
string CProject::GetProjectInfo()
{
string info = "";
info.append("項目名稱是:");
info.append(this->m_name);
info.append("\t項目人數:");
info.append(CConvert::ToString(m_num));
info.append("\t項目費用:");
info.append(CConvert::ToString(m_cost));
return info;
}
void CProject::Add( string name, int num, int cost )
{
this->m_projectList.push_back(new CProject(name, num, cost));
}
IProjectIterator * CProject::GetIterator()
{
return new CProjectIterator(this->m_projectList);
}
void CProject::Erase()
{
vector<IProject*>::reverse_iterator projectDelIt = m_projectList.rbegin();
for (; projectDelIt != m_projectList.rend(); projectDelIt++)
{
delete (*projectDelIt);
(*projectDelIt) = NULL;
}
m_projectList.clear();
}
//IIterator.h
#pragma once
class IProject;
class IIterator
{
public:
IIterator(void)
{
}
virtual ~IIterator(void)
{
}
virtual bool HasNext() = 0;
virtual IProject * Next() = 0;
};
//IProjectIterator.h
#pragma once
#include "iiterator.h"
class IProject;
class IProjectIterator :
public IIterator
{
public:
IProjectIterator(void)
{
}
virtual ~IProjectIterator(void)
{
}
virtual bool HasNext() = 0;
virtual IProject * Next() = 0;
};
//ProjectIterator.h
#pragma once
#include "iprojectiterator.h"
#include "IProject.h"
#include <vector>
using std::vector;
class CProjectIterator :
public IProjectIterator
{
public:
CProjectIterator(vector<IProject *> pl);
~CProjectIterator(void);
bool HasNext();
IProject * Next();
private:
vector<IProject *> m_projectList;
size_t m_currentItem;
};
//ProjectIterator.cpp
#include "StdAfx.h"
#include "ProjectIterator.h"
CProjectIterator::CProjectIterator(vector<IProject *> pl) : m_projectList(pl)
{
m_currentItem = 0;
}
CProjectIterator::~CProjectIterator(void)
{
}
bool CProjectIterator::HasNext()
{
bool b = true;
if (m_currentItem >= m_projectList.size())
b = false;
return b;
}
IProject * CProjectIterator::Next()
{
IProject *pp = m_projectList.at(m_currentItem ++);
return pp;
}
// Iterator.cpp
#include "stdafx.h"
#include "IProject.h"
#include "Project.h"
#include "..\CommonDeclare\Convert.h"
#include "ProjectIterator.h"
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
void DoIt()
{
cout << "----------未使用迭代模式----------" << endl;
vector<IProject*> projectList;
projectList.push_back(new CProject("星球大戰項目", 10, 100000));
projectList.push_back(new CProject("扭轉時空項目", 100, 10000000));
projectList.push_back(new CProject("超人改造項目", 10000, 1000000000));
for (int i = 4; i < 6; i ++)
{
string name = "";
name.append("第");
name.append(CConvert::ToString(i));
name.append("個項目");
projectList.push_back(new CProject(name, i * 5, i * 1000000));
}
vector<IProject*>::const_iterator projectIt = projectList.begin();
for (; projectIt != projectList.end(); projectIt++)
cout << (*projectIt)->GetProjectInfo().c_str() << endl;
vector<IProject*>::reverse_iterator projectDelIt = projectList.rbegin();
for (; projectDelIt != projectList.rend(); projectDelIt++)
{
delete (*projectDelIt);
(*projectDelIt) = NULL;
}
projectList.clear();
}
void DoNew()
{
cout << "----------使用迭代模式----------" << endl;
IProject *pproject = new CProject();
pproject->Add("星球大戰項目", 10, 100000);
pproject->Add("扭轉時空項目", 100, 10000000);
pproject->Add("超人改造項目", 10000, 1000000000);
for (int i = 4; i < 6; i ++)
{
string name = "";
name.append("第");
name.append(CConvert::ToString(i));
name.append("個項目");
pproject->Add(name, i * 5, i * 1000000);
}
IProjectIterator *pprojectIt = pproject->GetIterator();
while(pprojectIt->HasNext())
{
IProject *p = dynamic_cast<IProject*>(pprojectIt->Next());
cout << p->GetProjectInfo().c_str() << endl;
}
delete pprojectIt;
pprojectIt = NULL;
pproject->Erase();
delete pproject;
pproject = NULL;
}
int _tmain(int argc, _TCHAR* argv[])
{
//使用Iterator模式之前
DoIt();
//使用Iterator
DoNew();
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
_CrtDumpMemoryLeaks();
return 0;
}
這個模式,可能有一點繞,需要再仔細的思考一番。本來希望把模式的工作方式,用最簡單易懂的語言來總結,但其實這個總結更難。簡單的模式還容易些理解,也容易總結,複雜的就難了。打算在之後,學習數據結構的過程中,都總結出這樣一句話來。很期待後面對數據結構的學習,發現自己越來越愛學習了。