cs1ch5sec5.htm
 
 
CHAPTER 5
 
Object-Oriented Design
 

Section V: Defining Classes Section I: The Object-Oriented Paradigm Section II: Class Analysis and Design Section III : CRC Cards
Section IV: Classes in C++ Section VI: Using Class Declarations in a Program Section VII: Constructors Section VIII: Expanding the Idea of Classes


  


Table of Contents

Learning C++:
An Index of Entry Points


2. The

of C++

A reference document on the basic elements of C++.



3. The Patterns





A. Programmer Supplied Header Files
We now proceed to define the member functions which at this point is equivalent to defining the class. Just as with the code we saw in the last chapter, the definitions for member functions are usually kept separate from the declarations - and basically for the same reason - a class's declaration can be included a number of times but the definition can only be included once.

With classes the separations are usually more distinct. It is common practice to put the class declaration in one file, the class definition in a second file, and the program that uses the class in a third file. If there is more than one class in a program, each class gets its own declaration file and definition file. (Some programmers combine a number of class declarations in one file but the reasons for that are usually based on issues we have not discussed here.)

All the code we have written so far in this chapter represents a class declaration and should be in one file. As you may recall from our earlier work, all files should have at least two comment lines at the top providing the name of the file and a brief description of what the file is about. By convention, files that declare classes use the file extension '.h' - for 'header' file. We have already used one header file in the programs we wrote in earlier chapters - "iostream.h". That file was provided by the compiler distributors and we included it by using the "#include" directive followed by the file name surrounded by angle brackets, <...>. Its purpose is to declare the classes used for input and output. ]

Now that we are ready to write the definition for the Contract class, we need to open a new file. As usual this file begins with a set of comments describing what the file contains and its name:

// Definitions for the class Contract
// File: contract.cpp

Note that the file has the same name as the file containing the class declarations except that the extension is different. We use the .cpp extension because this file contains instructions for the individual functions. Since the specifications for the problem go in the file containing 'main' they do not appear here or in the '.h' file. From what we have learned already, what comes next is the line or lines to 'include' any necessary files. In our analysis above we decided to not have any of the functions provide for input or output. For that reason, we do not need to have the line:

#include <iostream.h>

in our code. However, there is one header file we do need to include. Our definitions for the class 'contract' are going to use the various elements of the 'contract' declaration and, therefore, that information needs to be available in this file. To make it available we need to include the header file for the contract class - the file we called 'contract.h'. This is accomplished using the code:

#include "contract.h"

You can think of the 'include' directive as telling the computer to copy in the code found in the file 'contract.h'. Note that the file name in the code is surrounded by double quote marks. This is to indicate that this is a programmer supplied header file and not a built-in one such as 'iostream.h'.

You might ask then why we don't just have one file that has the declarations and the definitions as we did in our previous programs. For simple programs such as the one we are presently working on we could do exactly that. However, this would not be wise in more complex programming situations. First, we have seen the importance of breaking our work up into pieces. For programs of thousands, hundreds of thousands, even millions of lines of code, having one file for the whole program would simply be unworkable. Second, we would like to have our code be re-usable. If someone writes a piece of code that provides specific functionality, it would be smart to include that code in any program that requires that functionality without including unnecessary additional code. Indeed, such re-usability is supposed to be a key feature of the object oriented approach. Once a class is declared and defined, it should be possible to use the code for that class in any programming problem requiring that class.

Third, when we break a large program up into separate files, the code in some of those files may need to know about some class. Thus, we may need to include the declaration code for that class in each of those files. We would not want, however, to include the class definitions in each file because, if we did so, the final, combined program would have more than one definition for the same member functions. This is illegal.

B. Defining Member Functions
The final answer to the question at this point might best be, "Trust the experience of professional programmers." Given that, let's proceed and begin defining the member functions for the class. It turns out that there is little new here other than the need for classname:: before each function definition.

The 'change' functions all are 'one-liners', for example:

void Contract::ChangeSquareFootage(int sqFootage)
{

squareFootage = sqFootage;
}

Note that aside from placing "Contract::" between the return type and the function name, this looks like any other function definition. The "Contract::" tells the compiler that this function is a member of the class 'Contract'.

The 'provide' functions are also one liners as in:

    int Contract::ProvideSquareFootage()
    {
    return squareFootage;
    }

The only 'provide' function that is different is the one we have already seen as different because it does a calculation:

    double Contract::ProvidePerWeekCharge ()
    {
      double perWeekCharge;
      perWeekCharge
              = numberOfDaysPerWeek * (0.05 * squareFootage + 5 * numberOfDesks);

      return perWeekCharge;
    }

A few points about this member function definition:

  1. Like all member functions, it contains "classname :: " between the return type and the function name.

  2. Since we decided to not have a separate data member for the "Per Week Charge", we need to declare a local variable here to hold its value.

  3. The variable names used in the instruction implementing the formula must match those found in the class declaration. These names represent the values in the data members for some specific instance of the 'contract' class. We will see in a moment how the system knows which instance to use.

  4. When the "Per Week Charge" is returned and the function is completed, the local variable 'perWeekCharge' disappears. In other words, the link between the variable name and a specific piece of memory is severed and the value is lost. (Since we decided above not to have a data member for the "Per Week Charge", this is just what we want to happen.)

Here then is the completed class definition:


// Definitions for the class Contract
// File: contract.cpp

#include "contract.h"

void Contract::ChangeSquareFootage(int sqFootage)
{ 	squareFootage = sqFootage;
}

void Contract::ChangeNumDesks( int numDesks)
{	numberOfDesks = numDesks;
}

void Contract::ChangeNumDays( int numDays)
{	numberOfDaysPerWeek = numDays;
}

int Contract::ProvideSquareFootage()
{	return squareFootage;
}

int Contract::ProvideNumberOfDesks()
{	return numberOfDesks;
}

int Contract::ProvideNumberOfDays()
{	return numberOfDaysPerWeek;
}

double Contract::ProvidePerWeekCharge ()
{	double perWeekCharge;
	perWeekCharge = 
                 numberOfDaysPerWeek * (0.05 * squareFootage + 5 * numberOfDesks);
	return perWeekCharge;
}

Top of Section Main Menu Next Section