Art Show | Course Home | Homework | Labs | Programming | Schedule & Lecture Notes | Submit

Saint Louis University

Computer Science P125
Introduction to Computer Science

Michael Goldwasser

Spring 2005

Dept. of Math & Computer Science

Lab 11

Time and Money


Introduction

Classes are the way programmers raise the level of abstraction in problem solving above the level of scalars (and vectors or arrays). In creating a class, the programmer is creating a re-usable representation of a concept used in problem solving. The more complex the class is, the less complex the rest of the program can be.

 

 

The objectives of this lab

 

Lab Problem

Your goal today is to write a program to accomplish the following task. Assume you have some tracks to burn to a CD and you need to know if they will fit. Pretending there isn't a better way to do this, you decide to write a program to add the times of the tracks together to see if they will fit within on one CD.  In doing so, we wish to have you develop your own Time classÉ

á     int hours

á     int minutes

á     float seconds

á     Time() -- constructor

á     void setTime(int, int, float) Ð set the value of a Time object with default parameter values

á     int getHours()

á     int getMinutes()

á     float getSeconds()

á     Time add (Time) Р returns the sum of  a Time object and another given Time

á     bool lessThan(Time) Ð find out if one Time is less than (or before) another

 

 

g++ -o burn burn.cpp time.cpp -Wall

 

 

 

 

Related Discussion

 

Rather than walk you through the precise design of your lab problem, the remainder of this document walks you through the design of a similar class,  namely one to represent Money.  You should read through this discussion, and hopefully can adapted the described techniques to design your own Time class.

 

Discussion : visibility modifiers

Suppose you have a problem that deals with money. You can represent dollars and cents as one double, it is not OK to have fractions of cents. An alternative is to represent dollars and cents as two values. Best is to create a class to represent money. We can begin with just (class header on left, program on right:

//file: money.h

class Money

{

    int dollars;

    int cents;

};

#include "money.h"

int main()

{

    Money mine, yours, sum;

 

    sum = mine + yours;  

}

Of course, we know from last week that the compiler does not know what to do with Money objects unless we define the methods. To be able to add Money objects, you must either overload the + operator, or define an addition method (the choice is a matter of stylistic preference). Seeing that we need an addition method, we could edit the header file to be (the ordering of things in the class is also a matter of stylistic-preference). Of course, also needed is the money.cpp file that defines how the money is added (we ignore this for the moment).

//file: money.h

class Money

{

    Money plus(Money);

    int dollars;

    int cents;

};

#include "money.h"

int main()

{

    Money mine, yours, sum;

 

    sum = mine.plus(yours);  

}

When attempting to compile this, there is an error. The compiler says something about plus being private. The correction is to make plus() public. The change is shown below. However, the change shown below makes everything public. The consequence is that a programmer using the time class can freely access the data members as well (i.e., dollars and cents), which makes the code on the right possible.

//file: money.h

class Money

{

   public:

    Money plus(Money);

    int dollars;

    int cents;

};

#include "money.h"

int main()

{

    Money mine, yours, sum;

    sum = mine.plus(yours);

    mine.cents = 100;

    yours.cents = -1000;

}

The code on the right should make you uncomfortable. It is possible to have cents values that make no sense. For example, there should never be a cents value greater than 99 or less than Ð99.  In addition, with the data members public it is possible to have positive dollars and negative cents (nonsense!). The fix is to make data member private. Data members should be private in every class. See changed code É

//file: money.h

class Money

{

   public:

    Money plus(Money);

   private:

    int dollars;

    int cents;

};

#include "money.h"

int main()

{

    Money mine, yours, sum;

    sum = mine.plus(yours);

 

    mine.cents = 100;      //illegal

    yours.cents = -1000;   //illegal

}

 

Discussion : default parameters

Now that the data members are private (and for good reason), we need methods for setting (and getting values) of Money objects. The natural thing to do is write void setDollars(int), setCents(int). This gets a little tedious. We could write a void setValue(int, int) method instead of the individual set methods. The class interface (a.k.a, the class header file) shown below has the new setValue() method. The code on the right shows the use of that method.

//file: money.h

class Money

{

   public:

    Money plus(Money additional);

    void setValue(int d, int c);

   private:

    int dollars;

    int cents;

};

#include "money.h"

int main()

{

    Money mine, yours, sum;

 

    mine.setValue(99, 0);  //$99.00

    yours.setValue(0, 99); //$0.99

 

    sum = mine.plus(yours);

}

Notice that when using the setValue() method, two values (i.e, dollars and cents) are needed even when the value is just a dollar value (no cents) or value a cents value (no dollars). One possible change (dare we say, improvement) is to provide a default parameter value for the setValue() method (see the change to the setValue() method in the money.h file, below on left). With the default value, the parameter with a default value becomes optional. See the example at the right, below.

//file: money.h

class Money

{

   public:

    Money plus(Money additional);

    void setValue(int d, int c = 0);

    void setDollars(int d);

    void setCents(int c);

    int getDollars();

    int getCents();

   private:

    int dollars;

    int cents;

};

#include "money.h"

int main()

{

    Money mine, yours, sum;

 

    mine.setValue(99);      // $99.00

    yours.setValue(0, 99);  // $0.99

 

    sum = mine.plus(yours);

}

When writing a method, it is acceptable (and often a good idea) to use other methods. In the implementation of setValue(), using the setDollar() and setCents() methods make setValue() easy. This is particularly true with the cents to dollars conversion provided by the setCents() method.

//file: money.cpp

 

#include "money.h"

 

void Money::setValue(int d, int c)

{

    setDollars(d);

    setCents(c);

}

//file: money.cpp

void Money::setCents(int c)

{

    cents = c % 100;

    dollars += c / 100;

}

void Money::setDollars(int d)

{

    dollars = d;

}

Discussion : constructors

Every class should have (at least) one constructor. A constructor is a method whose name is the same as the class. For Money class, every constructor of Money class is called Money. Constructors are used when an object is created. Notice there is no return type specified for a constructor.

//file: money.h

class Money

{

   public:

    Money();

    Money(int d, int c = 0);

    Money plus(Money additional);

    void setValue(int d, int c = 0);

    void setDollars(int d);

    void setCents(int c);

    int getDollars();

    int getCents();

   private:

    int dollars;

    int cents;

};

//file: money.cpp

 

#include "money.h"

 

Money::Money()

{

    dollars = 0;

    cents = 0;

}

Money::Money(int d, int c)

{

    setValue(d, c);

}

 

 

Discussion : separate compilation

Class construction is done in two parts (i.e,, interface and header, two files: .h and .cpp) and there is a separate program file. Compiling the class and the program can be done all together, or separately.

Compiling the class separately from the program allow you to avoid compiling the class when the program (but not the class) has changed. The class can be compiled into an object file. The object file is later linked to the program file that uses the class.