CSE 332S: Object Oriented Software Design Laboratory

Fall 2008: Lab 2

Due 11:59pm, February 7, 2006.

Purpose

This lab will give you some experience designing, implementing, and testing C++ classes. It will allow you to extend the code that you have written for previous labs, and move it C++.

Preparation

  1. Make sure that your code from lab 1 works as expected. If you want to, you can take our code as a starting point, although we recommend that you use your own code if possible.
  2. Make a lab2 directory, and grab a copy of the lab 2 code. Look at it, make yourself happy with it, compile it, and verify that it works.
  3. In this lab, we're going to ask you to talk about your design choices. For each step where you make a design choice, briefly explain why you made the choices you did in your README file.

Assignment

  1. Take the provided code, and change it so that it works with arrays of double variables, rather than arrays of int. This should be a simple change. Make sure everything still works.
  2. Implement the assignment operator. We have defined this in the private block, but you should move it back to the public block, and provide an implementation for it. Make sure you read the relevant parts of the book, and review your notes. This should be legal:
    Array a(10);
    Array b(10);
    Array c(10);
     
    a = b = c;
    but this should not
    Array a(10);
    Array b(5);
     
    a = b;
    You need to decide on the appropriate behavior (and document it in your README file).
  3. Add a new constructor that takes an addition double argument, and assigns this value to all elements of the array when it is created:
    Array a(10, 3.14);
    Make sure that you test this new functionality.
  4. Add some other operators to your class, so that the following code will work:
    Array array(10);
     
    array = 1.23; // Assignment operator (set all elements)
     
    double *p = array; // double * cast operator;
     
    cout << array << endl; // Output stream
    cin >> array; // Input stream
    Note that the assignment operator for this part is not the same as the assignment operator that is parameterized by another class instance (which you should already have). Remember to keep adding tests for the new code as you write it.

    For the functions that print out array values, do not print spaces between the array entries. This does not make much sense at the moment, but it will in a while. For example, if you have an array with four entries, 1.1, 2.2, 3.3, and 4.4, your print routines should print 1.12.23.34.4. A line like this

    cout << "A" << array << "A" << endl;
    should print out
    A1.12.23.34.4A
  5. Write a function that returns the size of the array as an int. Document any design choices in your README.
  6. Implement a function that will sort the values in the array into ascending order. Make sure it works as expected, and put in some debug code to check that it actually sorts the entries.
  7. Reimplement the first lab using your new array class. Keep your implementation to the lab2.cpp, Array.H, and Array.cpp files. Make sure that it passes all of the tests for the first lab. For this assignment, it is acceptable to ignore the requirement for specific precision in the output, since we haven't talked about stream formatting yet.
  8. Change the implementation of your code so that it takes an additional command line argument, -size n, which specifies the size of the array that you will be using.
    lab2 -size 100
    Will read in 100 lines from the standard input, sort them, and write them to the standard output.
    lab2 -size 100 --random
    Will generate 100 random numbers, and print them to the standard output. You will probably find atoi() useful for this part of the assignment.
  9. See how much it costs to do bounds checking in your code. Compile the code with all of the asserts enabled. Time how quickly it sorts a large array. You'll have to determine what "large" means for your code, since it will depend on your sorting algorithm. Start at 1000 and increase by factors of 10 until it takes a while to sort the array. Use the time command, and report the speed in your README file in plain English (ie don't cut and paste the output of time). Now, recompile the code with bounds checking turned off, and retime the same size of array. Report this in your README.

    Since you probably don't want to look at millions of doubles, you can send them directly to the null device, /dev/null. This is something that looks like a file, but which eats everything sent to it. It's also colloquially called the "bit bucket".

    lab2 --random > /dev/null

Grading

Most of the points in this lab will be for having the code work as described above. We will deduct points for the following things:
  1. Deviations from the design above, such as all of the code in a single source file, or not using function calls.
  2. Not compiling. If your code does not compile, then you will get no points for this lab.
  3. Warnings or errors in the compile. Your code should not generate any warning messages when compiled with the -Wall flag.

What to Hand In

You should hand in all of your code, your README, and your Makefile. As with the previous lab, make sure you list all of your source and header files in your Makefile. Further details on exactly how to do this will be available shortly.

Thoughts

  1. In C++ code, you should prefer iostreams to printf and friends. You should go though your code and make sure that all references to the printf functions are removed.
  2. There are a number of header files that are now deprecated for use with C++. These include a number of C header files, such as stdio.h. These files have been replaced with files that start with a c and lack the .h extension, cstdio. You should prefer these in your code.
  3. Make sure that you have include locks on your header files.
  4. Make sure that you don't have any using namespace std; statements in your header files, since this will pollute any files that include them.
  5. Beware of arrays of different lengths. Do not assume that all arrays will have the same length.
  6. You should make the input and output stream functions global functions, like the ones we showed in class. However, it's up to you to decide if they're friend functions or not. Remember to document your design decisions in the README file.
  7. Your code should be able to handle command line arguments in any order. This means that
    lab2 --random -size 2
    is the same as
    lab2 -size 2 --random
  8. You can assume that the input from the user will be well-formed, but you should not assume that the command-line arguments will be. In particular, you should do something sensible with mis-spelled command-line arguments, and sizes that are obviously wrong.
  9. You should sprinkle assert() through your code to catch potential problems early. Anywhere that you know bounds on the value of a variable is a candidate for an assertion.
  10. Comment your code sparingly. Tell us if you do anything interesting or unusual, but assume that we know x = 2; assigns a value of 2 to c. Please, don't try for humor, since it rarely improves cranky TAs moods.
Page written by Bill Smart.