iterators – external wrapping of a class

As from the previous iterator post that wraps around a class (or within it as such, since that is where the implementation is). Here I am showing how to do some external wrapping of the class.

Since I am using Linux (with the KDE GUI) with a develop environment called kDevelop I have included the files with there full source code in the above zip file.

In essence the iterator interfaces (abstract classes that make you implement the methods required to allow for the iterator to work) are as defined as

template <class T>
class iteratorInterface
{
    virtual bool hasNext() = 0;
    virtual T next() = 0;	// next will also return the value
    virtual T getValue() = 0;
};
 
template <class T>
class iteratorInterfaceBaseClass
{
     virtual T begin() = 0;
     virtual T end() = 0;
};

when the actual class that is going to have a iterator external wrapper will implement the iteratorInterfaceBaseClass interface (abstract class with pure virtual functions “virtual T begin() = 0” where the “=0” is the pure part). Here is the class that is going to have a iterator external wrapping, if you notice it also implements the iteratorInferfaceBaseClass, with the anotherStackIterator being the actual iterator for the anotherStack class.

class anotherStack : public iteratorInterfaceBaseClass<anotherStackIterator>
{
  private:
    int intArray[MAXSIZE];
    int lastAdded;
 
  public:
    anotherStack();
 
    bool addValue(int value);
    bool addValueAt(int value, int place);
 
    int returnValueAt(int place);
 
    // for the iterator, return this and also NULL basically
    anotherStackIterator begin();
    anotherStackIterator end();
};

and here is the anotherStackInterface class structure, this does the implementation of a standard (std::) iterator in a forward direction (std::forward_iterator_tag) with returning a int (eger) value.

class anotherStackIterator : public iteratorInterface<int>, public std::iterator<std::forward_iterator_tag, int>
{
  private:
      int theStackRef;
      anotherStack *theStack;
 
  public:
      anotherStackIterator(anotherStack *stackP)  : theStack(stackP) { theStackRef = 0;}
 
      bool operator==(const anotherStackIterator otherValue);
      bool operator!=(const anotherStackIterator otherValue);
      int operator++();
      int operator++(int);
 
      // as from the iteratorInterface
      bool hasNext();
      int next();
      int getValue();
};

in essence all you are doing is looping through the data that you implemented in the main class (anotherStack) how you want to, for example when you want to setup the iterator and then loop through like this

    anotherStack stacky;
    stacky.addValue(4);
    stacky.addValue(2);
    stacky.addValue(10);
 
 
    for (anotherStackIterator iter = stacky.begin(); iter!=stacky.end(); iter++)
    {
	printf("value %d\n", iter.getValue());
    }

the iterator (iter) has to implement the iter++ process, a way to increment the pointer to the next data item within the anotherStack data structure and here is how it is done

int anotherStackIterator::operator++()
{
    if (theStackRef < MAXSIZE)
      theStackRef++;
    return theStack->returnValueAt(theStackRef);
}

the theStackRef is just a integer value that holds the place within the integer array from the anotherStack class and all is what is returned a value within the data structure, but because in the loop there is a test against if the iterator value has reached the end of the array e.g. the != (not equal to) and here is the test for that

bool anotherStackIterator::operator!=(const anotherStackIterator otherValue)
{
    if (theStackRef >=MAXSIZE) 
	return false;
    if (otherValue.theStack == NULL)
	return true;
    return (theStack->returnValueAt(theStackRef) != otherValue.theStack->returnValueAt(otherValue.theStackRef));
}

the full source code is included within the zip file attached. I had fun doing this.

Leave a Reply

Your email address will not be published.