| |
Main Menu | Next Section |
Section V. Class Declarations for Contract and ListOfContracts
The good news is that we are finally ready to code. The bad news
is that the program will have to be extensively modified to deal
with the problems we just discussed. The bad news, however, is
not as bad as it seems. Usually, when a program needs to be rewritten,
it turns out that much of the code already written can be used - just in a modified
form. The difficulty in the rewriting process comes more from
being careful to write code that works than in the actual typing.
A. Preprocessor Directives
To make sure this program works, we should start from the
VERY beginning. If we created our own Boolean type (see Chapter 6, Section III, Part 'B'), this means starting with the file 'common.h'. This file includes the declarations necessary for the user-defined type, Boolean. A potential problem occurs in the fact that the Boolean type is used in both classes and in the main program.
Suppose we include the line:
in both class declaration files. Remember that the #include preprocessor
directive instructs the system
to copy the contents of a file into the file containing the directive.
In other words, both class declaration files will have the code found in 'common.h'. There is no problem here until we write the main program with '#include' commands to copy in both class declaration files. Now, all the code found in both files is copied into the main program which means that the code from 'common.h is included twice! That file has the lines:
which will result in an error because the constants TRUE and FALSE
would be defined twice!
This problem occurs all the time in C++, so there is a simple solution.
You should place another set of preprocessor directives:
at the top of all '.h' files ( 'dot h' files - meaning files that end in '.h' and are used as 'include' files).
And, at the bottom of all '.h' files include the line:
Here is 'common.h' with the added code:
// A set of basic type and function declarations common to many programs
typedef int Boolean;
const Boolean TRUE = 1;
const Boolean FALSE = 0;
#endif
When the system sees the new lines, it acts as follows:
The line
asks the question, "Has the term 'COMMON_H' been defined
yet?" The first time the file 'common.h' is read into a piece
of code, the answer is no and the next line is executed. This
line,
defines the term 'COMMON_H'. Afterwards, the rest of the lines
are executed ending with the line
and the system goes to the rest of the code in the file that has
directly or indirectly included 'common.h'.
If these lines are encountered again in the file, as they would
be in the case of our main program, the line,
is again processed but this time 'COMMON_H' has already been defined
so the lines from here to the line,
are skipped! Thus, the constants TRUE and FALSE are not declared
and defined again and there is no error. Note the purpose of the
'#endif'. Without it, the system would not know how many lines
to skip.
That is the only change in the file 'common.h'. With the existence of the built-in 'bool' type, there is no reason to use this 'common.h' file. However, it is strongly
recommended that you get in the habit of always including the three lines:
With the 'Contract' class the new code could look as follows:
B. Redeclaring the Contract Class
We now move onto the declarations for the class 'Contract'. The
need for an ID property in the this class causes a few additions
to the class declaration:
This new code can be viewed under the file name contrct2.h.
The file containing the definitions for this class, 'contrct2.cpp'
also has some changes:
C. The 'ListOfContracts' Class
Now it is time to declare the class 'ListfOfContracts'. There
is no new C++ to learn here here, but the way C++ features are used is different
and should be carefully studied. This is very common in programming
languages, as it is in any language - the same basic building blocks
can be put together in many novel ways.
// Class Declarations for ListOfContracts
// File: ch8list1.h
#ifndef LIST1_H
#define LIST1_H
#include "common.h"
#include "contrct2.h" // Uses the modified version of the contract class.
const int MAX_CONTRACTS = 5; // arbitrary number chosen for test purposes
typedef Contract ContractArray[MAX_CONTRACTS];
class ListOfContracts
{public:
ListOfContracts();
/*
Purpose: To instantiate (create) an instance of the class 'ListOfContracts'.
Goal: A new instance of class 'ListOfContracts' now exists
Receives: NONE
RETURNS: NONE
*/
void Add(Contract contract);
/*
Purpose: To add an instance of the class 'Contract' to the list.
Goal: A new instance of class 'contract' is on the list
Receives: a contract
Returns: NONE:
*/
void Delete(int contractNum);
/*
Purpose: To delete an instance of the class 'Contract' from the list.
Goal: The instance of class 'contract' is deleted
Receives: A contract number
Returns: NONE:
*/
bool FindContract(int ID, Contract& contract);
/*
Purpose: To find out if a contract is in the list and, if so, return it.
Goal: If the list holds a contract with id 'ID', the function
returns that contract in the variable 'contract' and
the function returns true
If not, the function returns false and 'contract' holds garbage.'
Receives: A contract ID
Returns: Whether or not the contract was found AND, if found, the
contract itself.
*/
void ReplaceContract (Contract contract);
/*
Purpose: To replace the properties of one contract in the list.
Goal: The properties of the contract in the list with the ID of
'contract' have been replaced. If there is no contract on the list
with this ID, an error message is displayed.
Receives: A contract
Returns: NONE
*/
void DisplayAll();
/*
Purpose: To display all the contracts in the list.
Goal: All the contracts are displayed on the screen
Receives: NONE
Returns: NONE
*/
private:
int numContracts; // indicates the number of contracts on the list and the next
// available slot in list
ContractArray listOfContracts;
};
#endif
The first thing to observe is that the constant and type definitions
have been moved from the file containing 'main' to here. The main
program will no longer have any use for the array itself. It will
only concern itself with the user defined types 'Contract' and
'ListOfContracts'. Being more precise, the programmer for the
main program will have no use for arrays. Remember the idea behind
the object oriented paradigm: Once a class, along with its properties
and behaviors, are defined by some programmer, other programmers
can use that class without caring at all how the internal
structure or behavior of that class is implemented.
Students have a tendency to fight this idea, but it really is key
to the way we function as humans. How many people know the principles
of aerodynamics that allow a plane to fly? Does that stop people
from flying? How many of us can explain how a microwave works? Not being able to provide such an explanation does not stop us from using a microwave on a regular basis. Given this, how is it so strange to think of one programmer designing a class and other programmers using it as if it were a 'black box' whose internals are unknown to the programmer-user? (And, by the way, this idea of a 'black box' is just what the idea of encapsulation is all about.)
What confuses people sometimes is that it is possible for one
programmer to act as both the designer and user of a class. However,
even this is typical human behavior. A person who designs airplanes probably does not think about such designs as he or she is flying to visit grand-ma. As a matter of fact, it is likely that he
or she does everything possible to keep from thinking about the
design so as to accomplish other things while flying. Maintaining
awareness of the internal workings of the airplane - or worse,
listening for 'noises' - only makes it difficult for him or her
to focus on other tasks. Similarly, once you as a programmer are
finished with work on a class or a function, it is best to forget
about the inner workings of your code, or you will not be able
to put your full attention on the next task.
Topics Covered in the "Essentials of C++"
| |
Main Menu | Next Section |