SHARE
Facebook X Pinterest WhatsApp

Iterating through List Containers

. When using containers in a program, I declare a class which represents an item in a container: // Can also be a struct class CMyClass : public CObject {     // Program specific     … }; typedef CTypedPtrList TMyList; Separate class (container) has the actual container object: class CMyClassList : public CObject {     […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Mar 2, 1999
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

.

When using containers in a program, I declare a class which represents
an item in a container:

// Can also be a struct

class CMyClass : public CObject {

    // Program specific

    …

};

typedef CTypedPtrList<CPtrList,CMyClass*>
TMyList;

Separate class (container) has the actual container object:

class CMyClassList : public CObject {

    private:

       
TMyList List;


       
// Maybe some other data members too


    public:

       
// Usual stuff (construction, destruction etc.)


       
void Flush(void);


       
BOOL Add(CMyClass *ptr);


       
CMyClass *Find(…);


       
BOOL Del(…);


};

If the container is associated with a user interface object (tree control,
list control etc.), one must iterate through the container and perform
an action for each item (or for those that satisfy some criteria). Easy
way to do it is to move a List variable to a public part of the class declaration
and then access it directly. This is bad since it violates a data encapsulation
principle (in all but trivial examples, class declaration has a lot more
member variables and methods and performs some useful job too).

One approach is to use a public member function and a supplied callback
function which is executed for each item. This is messy since supplied
callback function is usually a member function of another class so for
each different callback function, class CMyClassList must have an overloaded
member function. If a callback function is a static non-member function,
one must use a DWORD function argument to pass a “this” pointer to a static
callback function, then from within a callback function cast a DWORD to
pointer to a class object and then invoke a method which actually performs
some action with a container item.

Much easier and more elegant approach is to use special iterator class.
New class declaration is slightly modified:

class CMyClassListIterator;

class CMyClassList : public CObject {

    private:

       
TMyClassList List;


       
// Maybe something else


    public:

       
// Usual stuff (construction, destruction etc.)


       
void Flush(void);


       
BOOL Add(CMyClass *ptr);


       
CMyClass *Find(…);


       
BOOL Del(…);


    friend CMyClassListIterator;       
// New stuff


};

New iterator class is declared as follows:

class CMyClassListIterator : public CObject
{


  private:

    CMyClassList& Owner;

    POSITION Pos;

  public:

    CMyClassListIterator(TProcess&
obj)


             
:CObject(),Owner(obj) { Reset(); }


    void Reset(void)               
{ Pos = Owner.List.GetHeadPosition(); }


    void Next(void)                
{ Owner.List.GetNext(Pos); }


    CMyClass *Current(void)        
{ return (CMyClass*)Owner.List.GetAt(Pos); }


    BOOL IsDone(void)              
{ return (Pos == NULL) ? TRUE : FALSE; }


};

Now, all you need to do to iterate thru the list is to implement the
following peace of code:

CMyClassList MyList;

……..

CMyClassListIterator iterator(MyList);

while (!iterator.IsDone()) {

    CMyClass *ptr = iterator.Current();

    // Use ptr but do not
delete it.


    // You can modify its
contents however.


    iterator.Next();

};

You can also easily implement a nested iteration. Good side effect of
this implementation is that your code for list iteration is focused on
the job that must be done since all the code is implemented in one function
(no callbacks). Also, data encapsulation is preserved since List object
is not directly visible.

Recommended for you...

Video Game Careers Overview
CodeGuru Staff
Sep 18, 2022
Dealing with non-CLS Exceptions in .NET
Hannes DuPreez
Aug 5, 2022
Online Courses to Learn Video Game Development
Ronnie Payne
Jul 8, 2022
Best Online Courses to Learn C++
CodeGuru Staff
Jun 25, 2022
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.