CS321 -- Lab 2: Derived and Container Classes



->Courses
->CS321
-->Presentation
-->Lab 1
->Lab 2
-->Lab 3
-->Lab 4
-->Lab 5
-->Lab 6
-->Lab 7
-->Lab 8
->Electronic Submission
->Old Exams
->C++ Examples
->Unix Help
->Software
->Tentative Schedule
->Course Policies

[Courses]
[Rich][Home][Rich]
[Author]

Fall Quarter 2001

Purpose

The purpose of this lab is to review and develop basic skills in the programming of C++ derived and container classes.

Acknowledgement

This lab was developed by Dr. Henry Welch.

Preparation

Review your course materials from CS183 that pertain to the C++ mechanisms for base classes, derived classes, inheritance, and the use of the STL. You may find it helpful to refer to a polymorphism example I developed for my CS183 students. In addition, a glossary is provided.

Background

The field of computer graphics lends itself quite well to the use of base classes and derived classes. The ability of derived classes to inherit properties from a base class so that they do not have to be rewritten is quite powerful. In addition the ability to override and customize methods from the base class and to add new methods allows a derived class to customize itself for its own needs.

The files shape.h and shape.cpp declare and implement a base class called shape that might be appropriate for generic graphical shapes. It contains the following methods:

Method Description
Constructors The usual host of constructors:
No Argument
Copy
Assignment =
Destructor For removing dynamic data components
Draw Asks the shape to draw itself in a graphical area
Read Reads a shape from data file
Write Writes the shape to a data file
Xform Transforms the shape
Clone Allocates a new shape object, copies the current object, a returns a pointer to that object

A quick review of the code shows that it is very much a skeleton for what is needed to truly implement a shape. We will be using the shape class primarily as a convenient class type in which to refer to all shapes that have been derived from this class. As you progress through CS321 you may find it necessary to add new methods to the shape class or modify the existing ones.

The file image.h contains part of the declaration for a container class designed to hold pointers to shapes. By having it hold the base class shape pointer we can in effect have it contain any derived class shape pointer as well. Further, if we use the STL to build our data structure we must remember that it will only be storing copies of the pointers and not the objects themselves. In effect we will be requiring that all shapes must be allocated on the heap (via new) and that once added to the container the container will take responsibility for managing and deleting them in its destructor since the STL object will only delete the copy of the pointer.

The methods for this class are listed below.

Method Description
Constructors The usual host of constructors:
No Argument
Copy
Assignment =
Destructor Delete all the shapes from the container (the STL destructor will not do this) and delete all other dynamic objects.
Add Add a new shape pointer to the container
ReDraw Ask all the shapes to redraw themselves
Write Output all the shapes to a data file
Read Read a set of shapes from a data file (see below)
Xform Modify all the shapes in a image the same way
Zoom Zoom in on an image
Unzoom Zoom out on an image
Reset Revert an image to its "original" state
Erase Remove all the shapes from an image

By organizing things within a container class it will make it easier for other objects to conveniently manipulate an image. Again the methods are defined in a rather sketchy form since we as yet do not know exactly what information will be needed to implement the various methods in a real graphic environment. You can expect to add and modify this class throughout the term. You will notice that the data members have been left entirely up to you. One of the goals of this assignment is to have you choose an appropriate STL type for storing shapes. You may find that there are better choices than the vector or list.

Of all these methods the Read method may turn out to be the most difficult to implement. In most cases C++ can automatically pick the proper virtual method for derived class objects. All of this presupposes that the type of object is already known and created. When reading an object from a file or the terminal we do not know what kind of object we have until after we begin reading it. This presents somewhat of a dilemma. There have been a number of suggestions on how to solve this particular problem and often revolve around a special set of classes called factory or foundry classes. This is a nice abstract way to do this, but you may be able to approach the problem in a simpler fashion. Essentially each shape should contain a type field (see the QEvent as one example) which should always appear first in the data file. The Read method in this case will have to input the type field and then use a construct like the switch-case to determine which type of shape it is to create and then input. This requires that the container class Read method be updated every time we create a new kind of shape. Typically then, the factory class's job would be to do this for the container class and thus isolate the container class from this level of detail.

Laptop Linux Users

The instructions below are designed for students using their concord accounts. If you would prefer to conduct this lab assignment on your laptop, please follow these steps:

  1. Log on to concord
    1. Open a shell window (black screen in menu bar)
    2. Type ssh concord.msoe.edu and then log in
  2. Change to the following directory: /usr/local
  3. Make a tar archive of the cs321 directory by typing:
    tar -zcvf ~/cs321.tar.gz cs321
  4. Log off of concord
  5. Change to the following directory on your laptop:
    /mnt/win_d
  6. Transfer the file to the laptop:
    sftp concord
    get cs321.tar.gz
    quit
  7. Untar the file by typing:
    tar -zxvf cs321.tar.gz
  8. Change into the cs321 subdirectory.
  9. Save the following files in the cs321 subdirectory: shape.h, shape.cpp, image.h, and Imakefile
  10. Edit the Imake.tmpl file changing the first line in the file from:
    #include "/usr/local/cs321/Imake.rules"
    to
    #include "/mnt/win_d/cs321/Imake.rules
  11. Edit the Imake.rules file changing the line in the file from:
    INCLUDES = -I$(INCD) -I/usr/local/qt-2.3.0/include/
    to
    INCLUDES = -I$(INCD) -I/usr/lib/qt2/include/
    and the line:
    LIBS = -L$(LIBD) -L/usr/local/qt/lib/ -lqt -lcs321
    to
    LIBS = -L$(LIBD) -L/usr/lib/qt2/lib/ -lqt -lcs321
  12. Clean out the old binary files by typing:
  13. rm lib/* obj/*

Lab Activity

For this lab assignment you must do the following:

  1. Derive at least two different classes from the shape class. (point and line are two simple ones that you will need later.) Have each contain different data members and different versions of the virtual methods. Implement all of the member functions. (For Draw just have a suitable message sent to cout and have Xform make some change to derived shape.)
  2. Implement the image container class. For now have Zoom, Unzoom, and Reset do nothing. Have ReDraw call all the shape Draws and Xform call all the shape Xforms.
  3. Develop a testing program which instantiates at least one image object and then adds a mix of the derived shapes to the container. You may find that a small menu-driven approach works best. Test all of the methods to make sure they work correctly.
  4. Maintain a log of your activities so that you can document how you are spending time on this lab assignment. When you are done you should be able to report on how long you spent on each aspect of the assignment from planning to design to implementation, documentation and testing.
  5. You will find it useful to use a Imakefile with the following Imake Imake template to compile and link your code. (i.e. Copy these two files to your working directory, edit the Imakefile to reflect your file names and then execute the commands imake and then make lab2.) There is more information on imake available from the Wisconsin Regional Primate Research Center (no... I'm not joking).

Lab report (due 11pm, the day prior to week 4 lab)

Your lab report should be self-contained. That is, it should be possible for someone to understand what you did and why without seeing anything other than your report. Your report should include:

  • Purpose
  • Problem Statement
  • Procedure -- what approach you used to solve the problem
  • Discussion including:
    • An explanation for your choice of STL container for the image class. Be sure to identify the strengths and weaknesses of your choice and sell me on your decision. Also explain how you solved the container Read problem discussed above.
    • A description of your two derived shape classes so that someone else could understand what they are used for.
    • A tally of the number of Non-commented new Lines Of Code (NLOC) written for this lab assignment. You should use the CLC perl script on your code. Note: The first line of the file should be:
      #!/usr/bin/perl
      . It will report how many lines and statements of code you wrote. NOTE: For accurate results you should run it on the provided code first and then subtract that since you didn't write that code.
    • A summary of your activity log indicating how much time you spent on each phase of the assignment. Please report the time in the following categories:
      • Designing
      • Coding
      • Debugging (before you think it's working)
      • Testing (after you think it's working)
      • Report writing
      • Other
    • A narrative describing any specific problems you encountered and how you solved them.
  • Conclusions (what you learned, suggestions of how the lab could be improved, things you would have done differently, etc.)
  • Documented source code
    You may wish to use gensrc, a shell script which will produce an XML document that may be used as a starting point for your report. The file will include all of the source code files (provided you modify the script appropriately... edit gensrc for details on how to do this.)

As with any report you submit, correct spelling and grammar are required. In addition, your report should be submitted electronically following the Electronic Submission Guidelines. (You may wish to consult the sample report before submitting your report.) Be sure to keep copies of all your files, in case something gets lost. It may be wise to keep a diskette backup as well.

If you have any questions, consult the instructor.


Glossary

You may find some of these terms useful in reviewing derived classes and inheritance.

  • Abstract Class- A type of class with pure virtual member functions that behaves as a base class but prohibits the instantiation of any members of that class. It is used to take advantage of inheritance yet prohibiting the generation of objects that are not completely defined.
  • Base Class - A class from which other classes are derived. It usually provides a more generalized framework of data members and functions that are needed by all similar object.
  • Derived Class - A class that is obtained by inheriting data members and functions from a base class. A derived class usually adds specialization to a base class.
  • Inheritance - A mechanism where a derived class object also has the same data members and functions as an object from the base class from which the derived class was derived. NOTE: Constructors, destructors, and overloaded functions are not inherited. Additionally the base class constructor is always called before the derived class constructor and the base class destructor is always called after the derived class destructor.
  • Overloading - The creation of multiple functions with the same name yet dissimilar calling arguments (signature). This allows for the reuse of an appropriate name for multiple circumstances.
  • Overriding - When a derived class declares a member with the same name (the same signature is not required) the base class member is overridden and cannot be called directly from the derived class. This is common with virtual functions, but is not restricted to them. Care should be taken though when upcasting since a non-virtual overridden function will result in the base class version being called.
  • Polymorphism- The mechanism where an upcast version of a derived class object automatically finds the versions of member functions that are appropriate for the derived class.
  • Private - A designation for class members so that they are only accessible from member functions of that class or friends of that class.
  • Protected - A designation for class members so that they are only accessible from member functions of that class, member functions of derived classes, and friends of that class.
  • Public - A designation for class members so that they are accessible by anyone.
  • Pure Virtual - Any virtual member function in a base class which is declared =0 is said to not exist. (i.e., no definition will be provided.) Any class with pure virtual data members is an abstract class.
  • Slicing - When derived class objects are passed to functions and returned from functions as objects of the base class the extra derived class members are removed. This can be avoided by only passing derived class objects as pointers or as references. This way the entire object is passed not just the base class components. Due to limitations of the STL we will be using pointers to avoid this.
  • Static- A designation for class members that indicate that this member is shared by all objects of that class.
  • Upcasting - The action of referring to a derived class object as if it were an object of a base class. When doing this be sure to avoid slicing.
  • Virtual - A designation for class members that indicates that when a member of an upcast version of derived class object is accessed it uses the derived class version not the base class version.
© 1998-2001 Dr. Christopher C. Taylor Office: CC-27C Phone: 277-7339 Last Updated: September 19, 2001
I am responsible for all content posted on these pages; MSOE is welcome to share these opinions but may not want to.