C++ Lab - Introduction to Classes
Copy the header and implementation files of the example programs
from class to your directory. You may download them from the
following links or copy them as follows:
cp ~cpsc/public_html/Spring2009/CPSC270A/lab3/*.h .
cp ~cpsc/public_html/Spring2009/CPSC270A/lab3/*.cc .
Here are links.
Compiling and Linking
To compile a class and create an object file for the class we
compile the implementation file (which has a preprocessor directive
to include the header file). Compile the date class as follows
(if you changed the name of the file you need to change it here):
g++ -c date.cc
This creates the object file date.o.
To use the test program we also compile it to create an object file:
g++ -c testDate.cc
This creates the object file testDate.o. Now the object
files must be linked to create an executable. The following command
does this creating an executable named rundate.
g++ testDate.o date.o -o rundate
Run the program to make sure it works!
Makefiles
Note that with lots of files it can be tedious to go through all
the steps in the process of compiling and linking. A Unix utility
named make helps make this easier.
To use the make utility you must create a file named Makefile.
Makefile consists of pairs of lines in the following format:
target: dependencies
command for building the target
where target is the name of the file to be created, dependencies is
a list of files that target depends on, and the command for building
the target is the compilation command. For example, if we want
to compile date.cc to create the object file date.o, then the
Makefile entry is:
date.o: date.h date.cc
$(GCC) -c date.cc
Copy Makefile to your directory and examine
it. Note that at the top GCC is defined to mean g++ so g++ is substituted
for $(GCC) in the command.
The Makefile entry to link date.o and testDate.o to create the
executable rundate is as follows:
rundate: date.o testDate.o
$(GCC) testDate.o date.o -o $@
The target (in this case rundate) is substituted for $@.
To execute the commands to create a target you type
make target
at the command line. Try the following command:
make rundate
You may get a message saying rundate is up to date (if you haven't
made any changes since you last created rundate). If so, make
a small change to date.cc, save, then execute the make command
again.
How this works: When you type the make target
command, the entry for that target is examined. For each dependency,
the shell checks its dependency list (and so on up the chain of
dependencies) to see if any changes have occurred since the
corresponding target was last created. If any changes have been made
(or the target has not yet been created), the command is executed.
This continues back down the chain of dependencies until all
dependencies for your target are up to date. Then the command
for your target is executed.
What all this means is that everytime you make a change all you need
to do is type make finalTarget and all the necessary
re-compilations and linking will take place (and the unnecessary ones
won't).
Some Typical Errors in Using Classes
Do the following:
- In date.cc comment out the #include "date.h" preprocessor
directive. Recompile using the make command (make rundate).
What error messages do you get?
- Uncomment the preprocessor directive, then in the .h file
remove the semicolon at the end of the class declaration (after the
final end-brace). Recompile. What error messages do you get?
Put the semicolon back.
- Comment out the implementation of the leapYear method in
date.cc. Recompile. What happened?
Recompile. What happened? Why?
- In testDate.cc add parentheses to the declaration of
firstDate - that is, change it to
Date firstDate();
Compile to see what happens.
- Now change the statement so it looks like Java:
Date firstDate = new Date();
Compile to see what happens.
- Finally modify the statement so that firstDate is a pointer to
a Date object. Compile again. Leave firstDate as a pointer and change
any other statement(s) so that the program compiles and works
as it originally did.
Exercises involving the Makefile
Do the following:
- One syntax issue in Makefile -
the second line for each target must contain
a tab. Remove the tabs on the second line of the target rundate,
then type make rundate. What error message do you get? Put the
tabs back in.
- **** Add lines to Makefile so make can be used to compile
and link testDate2.cc. Make sure what you did works!
Operator Overloading
Recall that date2.h and date2.cc contain an enhanced version of the
Date class that includes 3 overloaded operators - the relational
operator ==, the insertion operator <<, and the increment operator ++.
- Compile date2.cc and testDate2.cc and link the resulting object
files to create an executable. Run the program to see how it works.
- **** Now add a function to overload the > (greater than) operator.
Your function should return true if this Date object is
"greater than" (later in the calendar) the Date passed as a parameter.
For example, 4/25/2009 is greater than 3/10/2009. Note
that you must add a prototype for the function in the header file
and implement the function in the .cc file. Be sure to document
your function. Make sure date2.cc compiles.
- **** Add a statement to testDate2.cc test your operator.
Run your program with several dates to make sure it works.
- **** Now add code to the class to overload
the extraction operator >>.
Your code should read the date as three integers (month followed
by day followed by year), separated by white space. The prototype
is as follows:
friend istream& operator >> (istream & stream, Date & d);
As with the insertion operator this is not a member function.
- **** Modify testDate2.cc to use >> to read in the dates.
Provide a helpful prompt for the user!
Test the program.
Working with Linked Lists
The linked list example we examined in class used two classes - a
SimNode class in which each node had two data fields (one for time
and one for type) and a pointer to the next SimNode, an OrderedList
class which was a linked list of SimNodes kept in ascending order
according to the time field, and a test program.
Separately compile the SimNode class (snode.cc), the OrderList class
(olist.cc), and the test program (testList.cc) to get object files.
Now link the files with the following command to get an executable
named runlist as follows:
g++ testList.o snode.o olist.o -o runlist
Run the program, comparing the behavior to the code.
Exercises: Open testList.cc and do the following:
- To see the errors when you confuse using the dot operator with
-> do the following:
- Change list.display() to list->display() then make runlist.
See what error message was generated.
- Correct the earlier error and now change node->display() to
node.display() then make runlist and see what error message is
generated.
- **** In the last loop that removes the nodes in the list one at a
time, change the 5 to a 6. Recompile and run. What happens?
Why did it happen? What would this error have been called in Java?
Write your answers somewhere to turn in (it can be in your email).
- **** Add the following to the OrderedList class:
- A data member length (type int) that keeps track of the
length of the list. Initialize and update the variable where needed.
- A member function that returns the length.
- A member function isEmpty that returns true if the list is empty
and returns false otherwise. (The return type should be bool.)
- **** Add appropriate statements in testList.cc to test the new member
functions.
Submit the following
Tar your directory that contains the files for this lab and send
the tar file as an attachment in an email. Please delete all .o files
before tarring.