分享
 
 
 

Ubiquitous Iterator (in English)

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Ubiquitous Iterator

This article is contributed by Wang HaiLong.

Preface

As one of 23 basic Design Patterns, Iterator seems to appear everywhere. This article discusses some scenarios where Iterator Pattern is applied, including STL, Collection in Java, IEnumXXXX interface in COM, IRowset interface in OLE DB, RecordSet Object in ADO, ResultSet in JDBC, Cursor in Oracle's SQL/PL.

Iterator Concept

Iterator Pattern separates the iteration operation from Container/Collection. To satisfy Iterator Pattern, there must be two Objects: a Container and its Iterator.

The aim of Iterator Pattern is to unify the way of iterating a Container, in spite of what kiand of data is put in the Container, and how the Container's internal structure is implemented.

The following is a simple example imitating STL.

// SimpleArray.cpp

template<typename T>

class SimpleArray

{

T data[100];

public:

class Iterator

{

SimpleArray<T>* m_pArray;

int m_iCurrentIndex;

friend class SimpleArray<T>;

public:

Iterator( SimpleArray<T>* pArray = 0) : m_pArray(pArray)

{

}

void Reset()

{

m_iCurrentIndex = 0;

}

T operator *()

{

return m_pArray->data[m_iCurrentIndex];

}

void operator --()

{

m_iCurrentIndex--;

}

void operator ++()

{

m_iCurrentIndex++;

}

bool operator !=(const Iterator& another)

{

if( m_pArray != another.m_pArray )

return true;

if( m_iCurrentIndex != another.m_iCurrentIndex )

return true;

return false;

}

};

Iterator begin()

{

Iterator it(this);

it.m_iCurrentIndex = 0;

return it;

}

Iterator end()

{

Iterator it(this);

it.m_iCurrentIndex = 100;

return it;

}

friend class Iterator;

};

template<class Container>

int sum(Container & con)

{

Container::Iterator it;

int total = 0;

for( it = con.begin(); it != con.end(); it++)

{

total += *it;

}

return total;

}

void test()

{

SimpleArray<int> con;

int total = sum(con);

}

If later we don't want to use the SimpleArray any more, we can change the test function as below.

#include <set>

void test()

{

set<int> con;

int total = sum(con);

}

Hence the separation of data structure and algorithm.

STL

The above example demonstrates the usage of STL and how to write STL-style programs. Now lets discuss some STL features in more depth.

As we have seen, algorithms can exist independent of data structure using STL. The key concept is "Function Object", which is detailed in chapter 21 "STL Algorithms" of <<Thinking in C++>>.

Now lets take a glimpse of what is a "Function Object".

Take the method "sort" of list in STL, for example.

template<class Pred> void sort(greater<T> pr);

The parameter pr inherits the "Function Object" greater and is also a "Function Object".

And the implementation likely takes the following shape.

struct CCompareTwoItem : public std::greater< T >

{

public:

bool operator()( T item1, T item2 )

{

}

};

Iterator in Java and C++

Enumeration interface and Iterator interface( in Java2) are self-explanatory. What is more, sub view is supported in Java.

similar effect can be approximated through filter iterator.

IEnumXXXX interface in COM

The definition of IEnumXXXX is:

Interface IEnumXXX : IUnknown

{

virtual HRESULT Next(unsigned long celt, XXXX* rgelt, unsigned long * pceltFetched) = 0;

virtual HRESULT Skip(unsigned long celt) = 0;

virtual HRESULT Reset() = 0;

virtual HRESULT Clone(IEnumXXXX** ppeunm);

}

An good example is "Connectable Objects" in COM.

interface IConnectionPoint : IUnknown

{

HRESULT GetConnectionInterface(IID* pIID);

HRESULT GetConnectionPointContainer(IConnectionPointContainer** ppCPC);

HRESULT Advise(IUnknown* pUnk, DWORD* pdwCookie);

HRESULT Unadvise(DWORD dwCookie);

HRESULT EnumConnections(IenumConnections** ppEnum);

}

interface IconnectionPointContainer : IUnknown

{

HRESULT EnumConnectionPoints(IEnumConnectionPoints** ppEnum);

HRESULT FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP);

}

interface IEnumConnectionPoints

{

HRESULT Next(ULONG cConnections, IConnectionPoint** rgpcn,ULONG* pcFetched);

HRESULT Skip(ULONG cConnections);

HRESULT Reset(void);

HRESULT Clone(IEnumConnectionPoints** ppEnum);

}

IConnectionPointContainer holds IConnectionPoint and IConnectionPointContainer's method EnumConnectionPoints returns an IEnumConnectionPoints which can iterate the IConnectionPointContainer to get every IConnectionPoint.

IRowset interface in OLE DB

IRowset method description:

AddRefRows Adds a reference count to an existing row handle.

GetData Retrieves data from the rowset's copy of the row.

GetNextRows Fetches rows sequentially, remembering the previous position.

ReleaseRows Releases rows.

RestartPosition Repositions the next fetch position to its initial position; that is, its position when the rowset was first created.

The definition of ICommand::Excute is:

HRESULT Execute (IUnknown* pUnkOuter, REFIID riid, DBPARAMS* pParams, LONG* pcRowsAffected, IUnknown** ppRowset);

This method returns an IRowset interface which can iterate through the result of "Excute".

RecordSet Object in ADO

The follow text is extracted from ADO help.

A Recordset object represents the entire set of records from a base table or the results of an executed command. At any time, the Recordset object only refers to a single record within the set as the current record.

Using the Open method on a Recordset object opens a cursor that represents records from a base table or the results of a query.

Ways to get RecordSet Object include:

On a Command object: Set recordset = command.Execute(RecordsAffected, Parameters, Options)

On a Connection object: Set recordset = connection.Execute(CommandText, RecordsAffected, Options)

ResultSet in JDBC

Connection Con = getConnection();

Statement stmt = con.createStatement(ResultSet.TYPE_SCROOL_INSENTIVE,

ResultSet.CONCUR_READ_ONLY);

ResultSet rs = stmt.excuteQuery(query);

While(rs.next()){c};

Cursor in Oracle's SQL/PL

We can look on Cursor as a forward-only iterator.

Appendix

Some great books about Design Patterns:

<<Design Patterns>> by Zurich, Sydney, Urbana, Hawthorne;

<<Thinking in C++>> and <<Thinking in Java >> by Bruce Eckel;

<<The Design Patterns Java Companion>> by James W. Cooper.

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有