UMBC, CMSC202 Computer Science II, Spring 2007
Project 5: Zoom Tables Revisited
Due Dates
Design Document: Sunday, May 6, 2007, 11:59pm + 59 seconds
Final Project: Sunday, May 13, 2007, 11:59pm + 59 seconds
Contents
Objective
The objective of this project is to practice writing C++ templates.
^Return to top
Background
For this programming project, you will make the ZoomTable class you
designed in Project 3 more useful
by:
- making the ZoomTable templated, so your client can define
ZoomTables of any underlying object,
- making ZoomTable member functions throw an exception when
an index out of bounds error is encountered, and
- adding row and column iterators to make efficient traversal
the rows and cols of the ZoomTable easier.
The first two improvements are straightforward. The third one needs
some explanation. You can look in Lab 13
for a basic explanation of iterators, but the root of the problem
is this. Suppose your client wants to do something with a row in
the ZoomTable. The code might look something like:
ZoomTable Z ;
...
for (int i = 0 ; i < Z.cols() ; i++) {
... Z.at(row,i) ;
}
This is terribly inefficient because every time your client makes a
call to Z.at(row,i), your at() function must find the Node with
coordinates (row,i) all over again. A loop that should take linear
time will instead take quadratic time. Although it is possible to
be efficient using the Zoom functions, it is cumbersome when all
your client wants to do is to step through a row of the ZoomTable.
This problem can be resolved using an iterator. The container classes
in the C++ Standard Template Library (STL) use many types of iterators,
you will implement a simple version here. The code for stepping
through a row of the ZoomTable looks like:
ZoomTable Z ;
ZTRowIterator it ;
int row = ... ;
for (it = Z.RowBegin(row) ; it != Z.RowEnd(row) ; it++) {
... *it ;
}
The iterator "it" remembers a position in a row of the ZoomTable
--- stepping to the next position takes constant time and does not
require any looping. The ZTRowIterator class must have the ++
and * (dereference) operators defined. The * (dereference) operator
returns a value of the underlying type, in this example an int.
The whole loop takes linear time and allows your client to
write code using a familiar-looking for loop.
^Return to top
Assignment
There are 3 parts to this project: make ZoomTables templated,
add exceptions, and add iterators.
Templated ZoomTable
This part of the project is straight forward, although you may be
spending some time with the compiler figuring out where you need
a <T> and where you don't.
The header file for ZoomTable should go in a file called
ZoomTable.H. The ZoomTable.cpp file holds the templated implementation.
ZoomTable.H should include ZoomTable.cpp at the bottom. (Other schemes
are prevalent and possibly better, but we need to stick to one format.)
All of the templated class definitions, including Node, ZTRowIterator
and ZTColIterator should go in ZoomTable.H.
There is one change in the ZoomTable requirement from Project 3.
Since we don't know the underlying type of a ZoomTable when we write
the template, we must require the client to supply us with the
default value of the table where we don't store a node. Thus, the
alternate constructor for ZoomTable is expanded to:
template
ZoomTable::ZoomTable(int rows, int cols, T d_value) ;
To test that your templated class actually works on a different
data type, create a class called Cup (defined and implemented in
Cup.h and Cup.cpp). You will use the ZoomTable to simulate the
ball-tossing game seen in many a county fair. Different colored
cups are laid out on a grid. You toss a plastic ball at the cups.
If the ball lands in a white cup, you get nothing. If it lands in
a red cup, you get a small prize. If it lands in a silver cup, you
get the grand prize.
Your Cup class must have at least two string data members for the
color of the cup and the prize associated with that cup. White is
the default value (and has no associated prize). Write a small
main program, cuptest.cpp, to exercise the ZoomTable functions.
{\it Note:} you need to implement an overloaded output operator
(<<) for your Cup class in order to have the dump() method
work properly.
ZoomTable Exceptions
Revise your code so your ZoomTable member functions throw an exception
when an index out of bounds error is encountered. The type of the
exception is ZTerror and is given in ZTerror.h.
Note that ZTerror is a data-only class and does not have any member
functions defined.
Requirements for the iterator classes
Two components are required for the iterators to work. You need
begin and end functions in ZoomTable and overloaded operators in
the iterator classes.
Add 4 member functions to your templated ZoomTable class:
ZTRowIterator RowBegin(int row) ;
ZTRowIterator RowEnd(int row) ;
ZTColIterator ColBegin(int col) ;
ZTColIterator ColEnd(int col) ;
The RowBegin() function should return a ZTRowIterator that represents
the coordinate (row,0) in the ZoomTable. Note that this is not
the FirstInRow() function, because we actually want column 0, even
if no Node is stored there. The RowEnd() function returns a
ZTRowIterator that represents a coordinate that is past the
last column of the ZoomTable. A typical for loop using iterators
ends when the condition it != Z.RowEnd(row) fails. This
happens when "it" is incremented beyond the last column and equals
the iterator returned by RowEnd().
The specifications for ColBegin() and ColEnd() are analogous.
The actual data you have stored in ZTRowIterator and ZTColIterator
depends on your design for ZoomTable. Think about how you will
represent coordinates where an actual Node is stored and coordinates
between two actual nodes.
The ZTRowIterator class must be templated and must support the
following methods:
- A default constructor:
ZTRowIterator() ;
- Comparison operators == and != :
bool operator==(const ZTRowIterator& rhs) const ;
bool operator!=(const ZTRowIterator& rhs) const ;
Two iterators are considered equal if they represent the same
coordinate in the ZoomTable. How this is done will vary greatly
depending on your design. The most important thing is that
while loops and for loops using these operators must terminate
properly.
- A dereference operator:
T operator*() const ;
Here T is the underlying type of the template. So, for ZoomTable dereferencing
a ZTRowIterator should return an int. If the iterator is representing a coordinate
without an actual Node stored, then the value returned is the default value
given to the ZoomTable constructor. (Note: the return value is not a reference,
so you cannot assign to a dereferenced ZTRowIterator.)
- A post-increment operator:
ZTRowIterator operator++(int dummy) ;
The dummy int parameter simply tells the compiler that this is the
post-increment (x++) rather than the pre-increment (--x) operator.
The return value should be a copy of the iterator before incrementing.
You may need to add other methods depending on your design. The
requirements do not specify the data members in ZTRowIterator. The methods
listed above should be public. It makes sense to have ZTRowIterator be
a friend of Node and/or ZoomTable. To do so, you will need to have
forward class declarations like:
template class ZTRowIterator ;
The requirements for ZTColIterator class are analogous.
Most designs will not have dynamically allocated data members
in ZTRowIterator or ZTColIterator. If your design for some reason
requires dynamically allocated data members, you will have to
implement a destructor, a copy constructor and an assignment operator.
^Return to top
Grading
- A design document is due on Sunday, May 6th, one week
before the final project. (See the Design
Document section.) The design document is 10% of the project
grade.
-
Projects will be graded on five criteria: correctness, design, style,
documentation and efficiency. So, turning in a project that merely "works"
is not sufficient to receive full credit.
-
Part of your grade will also depend on having demonstrated that you have
diligently tested your own program, by creating and submitting your
own test main program. (See the Testing section.)
- The Academic Conduct Policy for
this course states that programming projects must completed by you own
individual effort.
-
Remember that the late policy is
a 25% penalty for submissions up to 24 hours late. Projects more than
1 day late will receive zero.
^Return to top
Implementation Notes
- If your Project 3 is does not work, you will be
allowed to build on Prof. Chang's implementation of Project 3.
Details will be posted on the News section of the course website.
[Now available:
ZoomTable.h,
ZoomTable.cpp.]
- ZTRowIterator needs to know several things that
are stored in ZoomTable, including the default value of type T,
and the number of rows and cols. A simple way to make
these accessible is to store a pointer to the ZoomTable in
the ZTRowIterator (similar to what we did with RaceCourses
and Cars in Projects 2 and 4).
^Return to top
Design Document
You must submit written responses to these questions by Sunday,
May 6, 11:59:59pm. Late submissions are not accepted for design
documents.
Include the templated class definition for your ZTRowIterator. You
are not beholden to the exact definition for your final project,
but it will help in your answer to these questions:
- How will your ZTRowIterator represent the coordinates in a
ZoomTable that are in between two actual Nodes in a row? What
happens when you increment?
- After you increment a ZTRowIterator, how can you check
if you have gone past the last column?
- How will your ZTRowIterator * (dereference) operator know
when it should return the default value?
What/how to submit for your design document:
- Download the plain text file: design.txt.
The file has the 3 questions listed above.
- Insert your answers in the plain text file using
a text editor.
- Paste your ZTRowIterator class definition at the bottom of the
file.
- Submit the text file to the project 'proj5design' using the
Unix command:
submit cs202 proj5design design.txt
Please submit only 1 file.
^Return to top
Testing
You are provided with 2 main programs listed below. Your design and
implementation of ZoomTable classes must compile and run with
these 2 programs without any modification.
A separate main program will be posted shortly which tests
the exception handling part of your program.
[Now available as p5main3.cpp. See below.]
Warning: When your project is graded, it will also be tested
with additional main programs. So, having a project that works with
these programs is not a 100% guarantee. Your project must also
satisfy the requirements specified above.
Note: You were required to implement a Cup class and write
a program to test that the ZoomTable template actually worked on a
different data type. See the Assignment
section.
^Return to top
Submitting in your program
Remember to submit the design document the first week!
Use the UNIX submit command to turn in your project. The
project name for Project 5 is 'proj5'. So, the Unix command will
look like:
submit cs202 proj5 ...
where ... is a list of files you wish to submit.
You should submit the following files. Please follow the capitalization
and spelling of these files.
- ZoomTable.H: contains the templated class declaration for Node,
ZoomTable, ZTRowIterator and ZTColIterator.
- ZoomTable.cpp: contains the templated implementation for these classes.
- Cup.h: the class definition of your Cup class.
- Cup.cpp: the implementation of your Cup class.
- cuptest.cpp: the main program that tests your cup class.
Note: We will assume that your template will compile properly when
the main program, main.cpp, includes ZoomTable.H and is compiled using:
g++ -ansi -Wall main.cpp
and nothing else.
^Return to top