| |
Main Menu | Next Section |
VII. Defining the New Contract Class
The changes we will examine here are all due to the addition of
the string properties. In addition they are somewhat repetitious
because we perform the same basic set of operations over and over
on the different strings. For that reason, not all of the changes
will be explicitly discussed here. The complete code is under
the file name "contrct6.cpp". (Note that this file includes the file 'string.h' to have access to the two string manipulations functions (strlen and strcpy) used here.)
A. The Constructors
We begin with a look at the code for the first constructor:
Contract::Contract(int ID, int sqFootage, int numDesks, int numDays,
char* name, char* oStreetAddr, char* oCity,
char* oState, char* oZip)
{ contractID = ID;
squareFootage = sqFootage;
numberOfDesks = numDesks;
numberOfDaysPerWeek = numDays;
int len = strlen(name);
contracteeName = new char[len + 1];
strcpy(contracteeName, name);
len = strlen(oStreetAddr);
officeStreetAddress = new char[len + 1];
strcpy(officeStreetAddress,oStreetAddr);
len = strlen(oCity);
officeCity = new char[len + 1];
strcpy(officeCity,oCity);
len = strlen(oState);
officeState = new char[len + 1];
strcpy(officeState,oState);
len = strlen(oZip);
officeZip = new char[len + 1];
strcpy(officeZip,oZip);
}
Note that the parameter list does not include the default values.
They are only included in the declarations. The code to assign
the string parameters to the various string data members follows
a consistent format. The length of the string parameter is found;
enough memory for a string of that size (plus 1 for the null character)
is requested, and its address assigned to the corresponding data
member. Finally 'strcpy' is used to copy one string to the other.
The second constructor is the same with all the strings automatically made to be empty.
Contract::Contract()
{ contractID = 0;
squareFootage = 0;
numberOfDesks = 0;
numberOfDaysPerWeek = 0;
contracteeName = new char[1];
strcpy(contracteeName, "");
officeStreetAddress = new char[1];
strcpy(officeStreetAddress,"");
officeCity = new char[1];
strcpy(officeCity,"");
officeState = new char[1];
strcpy(officeState,"");
officeZip = new char[1];
strcpy(officeZip,"");
}
Since all the strings are empty, the are represented by one element
arrays - just enough room for the null character.
Now let's take a look at the code for the copy constructor.
Contract :: Contract(const Contract& c)
{ int len = strlen(c.contracteeName);
contracteeName = new char[len + 1];
strcpy(contracteeName, c.contracteeName);
len = strlen(c.officeStreetAddress);
officeStreetAddress = new char[len + 1];
strcpy(officeStreetAddress,c.officeStreetAddress);
len = strlen(c.officeCity);
officeCity = new char[len + 1];
strcpy(officeCity,c.officeCity);
len = strlen(c.officeState);
officeState = new char[len + 1];
strcpy(officeState,c.officeState);
len = strlen(c.officeZip);
officeZip = new char[len + 1];
strcpy(officeZip,c.officeZip);
contractID = c.contractID;
squareFootage = c. squareFootage;
numberOfDaysPerWeek = c.numberOfDaysPerWeek;
numberOfDesks = c.numberOfDesks;
}
Remember, the purpose of this is to copy the string properties.
The other properties are dealt with via straight assignment statements
as is shown in the last four lines of this function. To copy the
strings we write essentially the same code we saw in the first
constructor. Consider the code to copy the contractee name. First,
the code gets the length of the name to be copied:
Note that since this constructor is a member function of 'Contract',
it has access to the data members of any instance of 'Contract',
including 'c'. Also, note that since 'c' is not the instance that
was sent the message but, instead, was passed as a parameter,
we must use the syntax 'c.contracteeName'. In other words, the
code is referring explicitly to the name field of the instance
'c'. If we dropped the 'c' we would be referring to the instance
that was sent the message - the one that will receive the copied
data.
We have seen this dot notation used before in function
calls but not with data members. Up to now, we have not needed
to access the data members of one instance of a class while working
with a different instance of the same class. Instead, the code
that needed access to the data members of an instance was not
part of any member function and, therefore, had to use the public
member functions of the class in question. Since data members
usually are declared in the private part of a class declaration,
they are unknown outside the class and cannot be directly accessed
by code using the class. To repeat: it is legal to use the dot
notation with a data member of the 'Contract' class here because
this function is a member of the 'Contract' class and thus has
access to the data members of all instances of the class.
Once we have the length, we request enough memory for that many
characters plus 1 and assign the address to 'contracteeName'.
This time we do not place the 'c.' in front of the data member
name because we are referring to the new instance being created
not to the instance from which we are getting the data for this
new instance.
Finally, we make the copy using 'strcpy'. Note that here we use
both 'contracteeName' by itself and with the 'c.'. In other words,
we are copying the contents of 'c.contracteeName' to the 'contracteeName
data member of the new instance.
You will see that all the other string properties are handled the same way. Not only that, but the code for the 'CopyContract' member function is the same. It may seem strange that we need the same code in multiple places. The reason is that these functions have different purposes: one is a constructor, the other is used to copy from one existing instance to another. Any smart coder will not type this code twice. Instead he or she will use the copy and paste features of the editor extensively. When this code was written, one of the authors first wrote the first constructor. Then he copied the code to the copy constructor and added the dot notation. He was then finished with the copy constructor. Next, he copied this code to the 'CopyContract' function and had three 'complex' functions finished in no time.
B. The Destructor
We now move to the destructor. There are five arrays being pointed
to by data members of the class so we need five delete operations:
Contract :: ~Contract()
{ delete [] contracteeName;
delete [] officeStreetAddress;
delete [] officeCity;
delete [] officeState;
delete [] officeZip;
}
Remember that the [] is needed because each of these data members
points to an array.C. The Rest of the Function Members
The 'Provide...' and 'Change...' member functions are all similar
to each other except for the parameter and data member names used.
We will examine 'ProvideOfficeCity' and 'ChangeOfficeCity' here:
char* Contract:: ProvideOfficeCity()
{ return officeCity;
}
void Contract:: ChangeOfficeCity(char* city)
{ delete [] officeCity; // delete the whole string array
int len = strlen(city);
officeCity = new char[len + 1]; // don't forget the null char
strcpy(officeCity, city);
}
As with all 'Provide...' functions this one simply returns the
contents of the appropriate data member, 'officeCity'.
'ChangeOfficeCity' is a bit more complex. We are changing the
string contents of the 'officeCity' field and we don't know how
much memory will be required for the new string. The easiest way
to handle this is to return the memory used by the old string
and then request just the amount of memory required for the new
string. To return the memory, the first line of the function is
The rest of the code is exactly what we have done with every other
string assignment. In fact, this code was also copied from elsewhere
and modified to fit the variable names used here.
There is quite a bit of code to this modified version of the definitions
for 'Contract'. As noted, however, much of it is quite repetitive
and easily copyable. The trick in code like this is to understand
what needs to be done and then figure out how to do it as easily
as possible using the capabilities of your editor. Again, for
the complete code, check out contrct6.cpp
| |
Main Menu | Next Section |