Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Two questions Question1 : Look at the code in IteratorTest.cpp. What do you think it does? Compile the code (do you need to do anything

Two questions

Question1: Look at the code in IteratorTest.cpp. What do you think it does? Compile the code (do you need to do anything "unusual" to get it to compile?) and run it. Does it do what you think it would?

Take Away: Reminder of how to template class compilation, understanding of code.

Question2: Why do the iterator increment operators return an iterator? How do the two increment operators differ? Is the iterator they return allocated dynamically, auto, or something else?

Take Away: What does it mean to return a reference to self (in this case, and, in general, remember, overloaded operators typically return self).

SquareContainer2.h

#pragma once template class SquareContainer { public: class iterator; // forward declaration friend class iterator; // friend declaration /*! @class iterator This is a nested class. Note that it is in the public section of SquareContainer */ class iterator { public: /*! Initializes the iterator by associating it with a SquareContainer object, starting it at the beginning. */ iterator(SquareContainer* c, unsigned xloc = 0, unsigned yloc = 0) : theContainer(c), x(xloc), y(yloc) {} // You may need a copy constructor; we don't have it here // iterator(const iterator& it); // Prefix form of "next" operator iterator operator++(); // Postfix form of "next" iterator operator++(int); // Returns the current item T& operator*() const; // Comparison operators bool operator==(const iterator& rhs) const; bool operator!=(const iterator& rhs) const; private: /*! Keep track of where we are in theContainer */ unsigned x, y; /*! The SquareContainer object this iterator is associated with */ SquareContainer* theContainer; }; //Returns iterator that refers to first item, using iterator constructor iterator begin(void) { return iterator(this); } const iterator end(void) { return iterator(this, 0, ySize); } private: static const unsigned xSize = 5; static const unsigned ySize = 5; T contents[xSize][ySize]; }; // Remember, we can't compile template classes separately, so we // include it here and don't mention it on the command line. #include "SquareContainer2.cpp"

----------------------------------------------------------------------------------------------

SquareContainer2.cpp

#include #include using namespace std; #include "SquareContainer2.h" // Prefix form of "next" operator template typename SquareContainer::iterator SquareContainer::iterator::operator++() { // Don't do anything if we're already past the end if (y < theContainer->ySize) { if (++x >= theContainer->xSize) { x = 0; y++; } } return *this; } // Postfix form of "next" template typename SquareContainer::iterator SquareContainer::iterator::operator++(int) { iterator returnValue = *this; // Don't do anything if we're already past the end if (y < theContainer->ySize) { if (++x >= theContainer->xSize) { x = 0; y++; } } return returnValue; } // Returns the current item template T& SquareContainer::iterator::operator*() { // If we're past the end, it's really an error. You could throw an // exception, if you like. Make sure you document the iterator's // behavior in these circumstances. if (y >= theContainer->ySize) { cerr << "Attempt to dereference bad iterator; x=" << x << ", y=" << y << endl; exit(EXIT_FAILURE); } return theContainer->contents[x][y]; } template bool SquareContainer::iterator::operator==(const iterator& rhs) const { return (theContainer == rhs.theContainer) && (x==rhs.x) && (y==rhs.y); } template bool SquareContainer::iterator::operator!=(const iterator& rhs) const { return (theContainer != rhs.theContainer) || (x != rhs.x) || (y != rhs.y); }

----------------------------------------------------------------------------------------------

IteratorTest.cpp

#include using namespace std; #include "SquareContainer2.h" int main() { // You create a container like so: SquareContainer mc; // and use it in various ways: SquareContainer::iterator ci = mc.begin(); unsigned i = 1; while (ci != mc.end()) { cout << "Setting element " << i << endl; *(ci++) = i++; } for (SquareContainer::iterator ci = mc.begin(); ci != mc.end(); ++ci) { cout << *ci << endl; } }

----------------------------------------------------------------------------------------------

NoTemplate/IteratorTest.cpp

#include  using namespace std; #include "SquareContainer2.h" int main() { // You create a container like so: SquareContainer mc; // and use it in various ways: SquareContainer::iterator ci = mc.begin(); unsigned i = 1; while (ci != mc.end()) { cout << "Setting element " << i << endl; *(ci++) = i++; } for (SquareContainer::iterator ci = mc.begin(); ci != mc.end(); ++ci) { cout << *ci << endl; } }

----------------------------------------------------------------------------------------------

NoTemplate/SquareContainer2.cpp

#include  #include  using namespace std; #include "SquareContainer2.h" // Prefix form of "next" operator SquareContainer::iterator SquareContainer::iterator::operator++() { // Don't do anything if we're already past the end if (y < theContainer->ySize) { if (++x >= theContainer->xSize) { x = 0; y++; } } return *this; } // Postfix form of "next" SquareContainer::iterator SquareContainer::iterator::operator++(int) { iterator returnValue = *this; // Don't do anything if we're already past the end if (y < theContainer->ySize) { if (++x >= theContainer->xSize) { x = 0; y++; } } return returnValue; } // Returns the current item int& SquareContainer::iterator::operator*() { // If we're past the end, it's really an error. You could throw an // exception, if you like. Make sure you document the iterator's // behavior in these circumstances. if (y >= theContainer->ySize) { cerr << "Attempt to dereference bad iterator; x=" << x << ", y=" << y << endl; exit(EXIT_FAILURE); } return theContainer->contents[x][y]; } bool SquareContainer::iterator::operator==(const iterator& rhs) const { return (theContainer == rhs.theContainer) && (x==rhs.x) && (y==rhs.y); } bool SquareContainer::iterator::operator!=(const iterator& rhs) const { return (theContainer != rhs.theContainer) || (x != rhs.x) || (y != rhs.y); }

----------------------------------------------------------------------------------------------

NoTemplate/SquareContainer2.h

#pragma once class SquareContainer { public: class iterator; // forward declaration friend class iterator; // friend declaration /*! @class iterator This is a nested class. Note that it is in the public section of SquareContainer */ class iterator { public: /*! Initializes the iterator by associating it with a SquareContainer object, starting it at the beginning. */ iterator(SquareContainer* c, unsigned xloc = 0, unsigned yloc = 0) : theContainer(c), x(xloc), y(yloc) {} // You may need a copy constructor; we don't have it here // iterator(const iterator& it); // Prefix form of "next" operator iterator operator++(); // Postfix form of "next" iterator operator++(int); // Returns the current item int& operator*() const; // Comparison operators bool operator==(const iterator& rhs) const; bool operator!=(const iterator& rhs) const; private: /*! Keep track of where we are in theContainer */ unsigned x, y; /*! The SquareContainer object this iterator is associated with */ SquareContainer* theContainer; }; //Returns iterator that refers to first item, using iterator constructor iterator begin(void) { return iterator(this); } const iterator end(void) { return iterator(this, 0, ySize); } private: static const unsigned xSize = 5; stat const unsigned ySize = 5; int contents[xSize][ySize];

};

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access with AI-Powered Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions