This chapter takes a deeper look at classes. We use an integrated Time
class case study and other examples to demonstrate several class construction capabilities. We begin with a Time
class that reviews several of the features presented in preceding chapters. The example also demonstrates using an include guard in headers to prevent header code from being included in the same source code file more than once.
We demonstrate how client code can access a class’s public
members via 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 write an object’s data members. 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.
We show how to pass arguments to constructors and show how default arguments can be used in constructors to enable client code to initialize objects using a variety of arguments. Next, we discuss a special member function called a destructor that’s part of every class and is used to perform “termination housekeeping” on an object before it’s destroyed. We demonstrate the order in which constructors and destructors are called.
We show that returning a reference or pointer to private
data breaks the encapsulation of a class, allowing client code to directly access an object’s data. We use default memberwise assignment to assign an object of a class to another object of the same class.
We use const
objects and const
member functions to prevent modifications of objects and enforce the principle of least privilege. We discuss composition—a form of reuse in which a class can have objects of other classes as members. Next, we use friendship to specify that a nonmember function can also access a class’s non-public
members—a technique that’s often used in operator overloading (Chapter 10) for performance reasons. We discuss the this
pointer, which is an implicit argument in all calls to a class’s non-static
member functions, allowing them to access the correct object’s data members and non-static
member functions. We motivate the need for static
class members and show how to use them in your own classes.