A class’s private
data members can be manipulated only by member functions of that class (and by “friends” of the class as you’ll see in Chapter 9). So a client of an object—that is, any statement that calls the object’s member functions from outside the object—calls the class’s public
member functions to request the class’s services for particular objects of the class. This is why the statements in function main
call member functions setCourseName
, getCourseName
and displayMessage
on a GradeBook
object. Classes often provide public
member functions to allow clients of the class to set (i.e., assign values to) or get (i.e., obtain the values of) private
data members. These member function names need not begin with set
or get
, but this naming convention is common. In this example, the member function that sets the courseName
data member is called setCourseName
, and the member function that gets the value of the courseName
data member is called getCourseName
. Set functions are sometimes called mutators (because they mutate, or change, values), and get functions are also called accessors (because they access values).
Recall that declaring data members with access specifier private
enforces data hiding. Providing public
set and get functions allows clients of a class to access the hidden data, but only indirectly. The client knows that it’s attempting to modify or obtain an object’s data, but the client does not know how the object performs these operations. In some cases, a class may internally represent a piece of data one way, but expose that data to clients in a different way. For example, suppose a Clock
class represents the time of day as a private int
data member time
that stores the number of seconds since midnight. However, when a client calls a Clock
object’s getTime
member function, the object could return the time with hours, minutes and seconds in a string
in the format "HH:MM:SS"
. Similarly, suppose the Clock
class provides a set function named setTime
that takes a string
parameter in the "HH:MM:SS"
format. Using string
capabilities presented in Chapter 19, the setTime
function could convert this string
to a number of seconds, which the function stores in its private
data member. The set function could also check that the value it receives represents a valid time (e.g., "12:30:45"
is valid but "42:85:70"
is not). The set and get functions allow a client to interact with an object, but the object’s private
data remains safely encapsulated (i.e., hidden) in the object itself.
The set and get functions of a class also should be used by other member functions within the class to manipulate the class’s private
data, even though these member functions can access the private
data directly. In Fig. 3.5, member functions setCourseName
and getCourseName
are public
member functions, so they’re accessible to clients of the class, as well as to the class itself. Member function displayMessage
calls member function getCourseName
to obtain the value of data member courseName
for display purposes, even though displayMessage
can access courseName
directly—accessing a data member via its get function creates a better, more robust class (i.e., a class that’s easier to maintain and less likely to malfunction). If we decide to change the data member courseName
in some way, the displayMessage
definition will not require modification—only the bodies of the get and set functions that directly manipulate the data member will need to change. For example, suppose we want to represent the course name as two separate data members—courseNumber
(e.g., "CS101"
) and courseTitle
(e.g., "Introduction to C++ Programming"
). Member function displayMessage
can still issue a single call to member function getCourseName
to obtain the full course name to display as part of the welcome message. In this case, getCourseName
would need to build and return a string
containing the courseNumber
followed by the courseTitle
. Member function displayMessage
could continue to display the complete course title “CS101 Introduction to C++ Programming
.” The benefits of calling a set function from another member function of the same class will become clearer when we discuss validation in Section 3.8.
Always try to localize the effects of changes to a class’s data members by accessing and manipulating the data members through their corresponding get and set functions.
Software Engineering Observation 3.1
Write programs that are clear and easy to maintain. Change is the rule rather than the exception. You should anticipate that your code will be modified, and possibly often.