9.1. Introduction
In the preceding chapters, we
introduced many basic terms and concepts of C++ objectoriented programming. We
also discussed our program development methodology: We selected appropriate
attributes and behaviors for each class and specified the manner in which
objects of our classes collaborated with objects of C++ Standard Library classes
to accomplish each program's overall goals.
In this chapter, we take a deeper look
at classes. We use an integrated Time class case study in both this
chapter (three examples) and Chapter
10, Classes: A Deeper Look, Part 2 (two examples) to
demonstrate several class construction capabilities. We begin with a
Time class that reviews several of the
features presented in the preceding chapters. The example also demonstrates an
important C++ software engineering concept—using a "preprocessor wrapper" in
header files to prevent the code in the header from being included into the same
source code file more than once. Since a class can be defined only once, using
such preprocessor directives prevents multiple definition errors.
Next, we discuss class scope and the
relationships among members of a class. We also demonstrate how client code can
access a class's public members via three types
of "handles"—the name of an object, a reference to an object or a pointer to an
object. As you'll see, object names and references can be used with the dot
(.) member selection operator to access a
public member, and pointers can be used with the
arrow (->) member selection operator.
We discuss access functions that can read
or display data in an object. A common use of access functions is to test the
truth or falsity of conditions—such functions are known as predicate functions.
We also demonstrate the notion of a utility function (also called a helper
function)—a private member function that
supports the operation of the class's public
member functions, but is not intended for use by clients of the class.
The second example of the Time
class case study demonstrates how to pass arguments to constructors and shows
how to use default arguments in a constructor to enable client code to
initialize objects of a class using a variety of arguments. Next, we discuss a
special member function called a
destructor that is part of every class and is used to perform "termination
housekeeping" on an object before the object is destroyed. We then demonstrate
the order in which constructors and destructors are called, because your
programs' correctness depends on using properly initialized objects that have
not yet been destroyed.
Our last example of the Time class case study in this chapter shows a dangerous
programming practice in which a member function returns a reference to
private data. We discuss how this breaks the
encapsulation of a class and allows client code to directly access an object's
data. This last example shows that objects of the same class can be assigned to
one another using default memberwise assignment, which copies the data members
in the object on the right side of the assignment into the corresponding data
members of the object on the left side of the assignment. The chapter concludes
with a discussion of software reusability.