|
Table of Contents
Learning C++:
An Index of Entry Points
2. The A reference document on the basic elements of C++.
3. The Patterns
|
A. Viewing Data Members as a Structure We have already talked in general about the two data members for this
class. The second one, 'listOfContracts' is an array. We know this from
the code because it is declared to be of type 'ContractArray' - the type
we declared at the top of the file. By the way, note that the class is
named 'ListOfContracts' with an upper case 'L', while our array has the
same name, except that we use a lower case 'l'. Some people think this is
neat, others feel it just adds to the confusion. You decide for yourself
in your own work. The first data member, 'numContracts', is the counter we talked about
above. When the list is empty, it has the value 0, when one element is in
the list, it has the value 1, etc. Note the relationship between
'numContracts' and 'listOfContracts'. The data member 'numContracts' tells
the system which elements of 'listOfContracts' hold actual contracts and
which ones hold garbage. These two data members make up a structure that we can use to represent
a list. Such a structure is only useful, however, if there are also
functions to manipulate it. Developing these is our next step. B. OverView of the Member Functions - Declarations and
Definitions
The declarations are in the file ch8list1.h. We are now ready for the function
definitions in the file 'ch8list1.cpp'. C. The Constructor D. The 'Add' Member Function
This causes the contract in the variable 'contract' to be copied to the
memory location 'listOfCOntracts[0]'. After this, 'numContracts' is
incremented to 1 and the next time an add takes place, the new contract
will be placed in the memory location symbolized by '
'listOfContracts[1]'.
(Be sure you understand that the values 0 and 1 used here refer to the
values held by 'numContracts' at different times.) Let's step back and go over this function from the top. The first step
is to make sure that there is not already a contract in the list with the
ID of the new contract. (Duplicates can't be allowed if we want to be able
to delete a contract based on it's ID.) The line gets the ID of the contract to be added and the while loop examines all
the contracts to check for a duplicate. Here we see another use of a
boolean variable. A search can end for two reasons:
Thus, there are two test conditions in the while loop. Note that
'found' is initially set to false to indicate that a match has not been
found when the loop starts. One by one, the loop compares the contracts in
the list (using 'index' as the subscript into the array of contracts) with
the ID of the new contract (as stored in 'contractNum'). If a match
occurs, found is set to true and this is used to stop the search loop. If
there is no match, 'index' is incremented and the next element in the
array is used in the comparison. Eventually, if some contract in the list
has an ID equal to the ID in 'contractNum', the loop will stop, with the
'index' acting as an indicator of which element in the array had the
match. If there is no match in the list, the loop will eventually stop
when 'index' reaches 'numContracts'. In this case, 'found' is never set to
true. Note that the code does NOT search the whole array. It only checks
those array elements that actually hold contracts – as indicated by the
value in 'numContracts'. (If the whole array were checked, the 'while'
test would have used MAX_CONTRACTS instead of 'numContracts'.) The second step is to insert the contract if no match was found. The
line:
performs the check to make sure there was no match. If so, the contract
is added to the list and the number of contracts is incremented. The rest
of the code simply adds appropriate messages. E. The 'Delete' Member Function
The test here is the opposite of the test in 'Add' because the action
takes place only if a match exists - one cannot delete something if it is
not there to be deleted. The other main difference in the code is in the lines:
A contract is not so much deleted as written over. In this code it is
written over by the last contract in the list. Since the list of contracts
is not sorted and, therefore, there is no concern about the order of
contracts, it makes complete sense to simply move the last contract into
the deleted contracts spot. Of course, the last contract now exists in two
elements of the array - where it was before the copy and in the location
containing the contract to be deleted. However, once we decrement
'numContracts' by one, there is no problem because the original location
for the contract being copied is now considered to contain garbage.
One might ask why we copy from element "numContracts -1". Remember,
'numContracts' indicates the next available spot in the array. Therefore,
"numContracts -1" indicates the "last used" element of the array.
An example: Consider a list containing five contracts (C1 through C5)
and a maximum capacity of 10 contracts. Figure 8.5 show how memory might
look at this point.
If
contract C2 is to be deleted from a list, the goal is to copy contract C5
into the spot containing C2. C5 is in element 4 and C2 is in element 1 --
remember C++ arrays count from 0. The search code should have found C2 in
element one and therefore placed the value 1 in 'index'. The code:
will change the picture of memory as shown in figure 8.6.
Contract 'C2' no longer exists while contract 'C5' is in two
places. However, 'numContracts' now has the value 4 so the second 'C5', in
element 5 of the array, is no longer seen as part of the list. This is a
subtle point, so consider it carefully and create your own examples to
convince yourself that this works.
F. 'FindContract', ReplaceContract'
and "DisplayAll' When a system encounters a 'return' statement it immediately leaves
whatever function it is in. Thus, when the line: is encountered in 'FindContract', the code leaves the loop in the
process of leaving the whole function. (Notice that if a match is found,
this function also places the matching contract into the parameter
'contract' and this contract is then also returned.) As long as a match is
not found, the index variable is incremented and the loop continues. If
the loop terminates for any other reason, than when a match is found, it
can only be because all contracts in the list have been examined. This
means that no matching ID was found in the list and the function returns
false. 'ReplaceContract' is yet another example of the same search/action
pattern. This time, the goal is to find the location of the contract to be
replaced and then copy into that location the contract passed as a
parameter. The 'else' part of the 'if' statement in the code for this
function is mostly for debugging. Used properly, there should always be a
match. However, one should always code defensively and consider the
possibility of the impossible! The last function, 'DisplayAll', is different but very simple. The code
shows us why we decided to make this a member function. It is so easy to
simply walk through the list using a 'for' loop to output the property
values of all the contracts. Note that 'contract' is used here in the way
'index' was used above and that the loop tests for:
instead of comparing ' contract' with MAX_CONTRACTS. The goal is to
display all the contracts that actually exist, not the values in all
possible contract locations.
|