3.4. Defining a Class with a Member Function

We begin with an example (Fig. 3.1) that consists of class GradeBook (lines 9–17), which represents a grade book that an instructor can use to maintain student test scores, and a main function (lines 20–25) that creates a GradeBook object. Function main uses this object and its member function to display a message on the screen welcoming the instructor to the grade-book program.

Fig. 3.1. Define class GradeBook with a member function displayMessage, create a GradeBook object, and call its displayMessage function.

 

 1   // Fig. 3.1: fig03_01.cpp
 2   // Define class GradeBook with a member function displayMessage,
 3   // create a GradeBook object, and call its displayMessage function.
 4   #include <iostream>
 5   using std::cout;
 6   using std::endl;
 7
 8   // GradeBook class definition                                       
 9   class GradeBook                                                     
10   {                                                                   
11   public:                                                             
12      // function that displays a welcome message to the GradeBook user
13      void displayMessage()                                            
14      {                                                                
15         cout << "Welcome to the Grade Book!" << endl;                 
16      } // end function displayMessage                                 
17   }; // end class GradeBook                                           
18
19   // function main begins program execution
20   int main()
21   {
22      GradeBook myGradeBook; // create a GradeBook object named myGradeBook 
23      myGradeBook.displayMessage(); // call object's displayMessage function
24      return 0; // indicate successful termination
25   } // end main

					  

Welcome to the Grade Book!


First we describe how to define a class and a member function. Then we explain how an object is created and how to call a member function of an object. The first few examples contain function main and the GradeBook class it uses in the same file. Later in the chapter, we introduce more sophisticated ways to structure your programs to achieve better software engineering.

Class GradeBook

Before function main (lines 20–25) can create an object of class GradeBook, we must tell the compiler what member functions and data members belong to the class. The GradeBook class definition (lines 9–17) contains a member function called displayMessage (lines 13–16) that displays a message on the screen (line 15). Recall that a class is like a blueprint—so we need to make an object of class GradeBook (line 22) and call its displayMessage member function (line 23) to get line 15 to execute and display the welcome message. We'll soon explain lines 22–23 in detail.

The class definition begins in line 9 with the keyword class followed by the class name GradeBook. By convention, the name of a user-defined class begins with a capital letter, and for readability, each subsequent word in the class name begins with a capital letter. This capitalization style is often referred to as camel case, because the pattern of uppercase and lowercase letters resembles the silhouette of a camel.

Every class's body is enclosed in a pair of left and right braces ({ and }), as in lines 10 and 17. The class definition terminates with a semicolon (line 17).

Common Programming Error 3.1

Forgetting the semicolon at the end of a class definition is a syntax error.


Recall that main is called automatically when you execute a program. As you'll soon see, you must call member function displayMessage explicitly to tell it to perform its task.

Line 11 contains the access-specifier label public:. The keyword public is an access specifier. Lines 13–16 define member function displayMessage. This member function appears after access specifier public: to indicate that the function is "available to the public"—it can be called by other functions in the program (such as main), and by member functions of other classes. Access specifiers are always followed by a colon (:). For the remainder of the text, when we refer to the access specifier public, we'll omit the colon as we did in this sentence. Section 3.6 introduces a second access specifier, private.

Each function in a program performs a task and may return a value when it completes its task—for example, a function might perform a calculation, then return the result of that calculation. When you define a function, you must specify a return type to indicate the type of the value returned by the function when it completes its task. In line 13, keyword void to the left of the function name displayMessage is the function's return type. Return type void indicates that displayMessage will not return any data to its calling function (in this example, main, as we'll see in a moment) when it completes its task. In Fig. 3.5, you'll see an example of a function that returns a value.

The name of the member function, displayMessage, follows the return type. By convention, function names begin with a lowercase first letter and all subsequent words in the name begin with a capital letter. The parentheses after the member function name indicate that this is a function. An empty set of parentheses, as shown in line 13, indicates that this member function does not require additional data to perform its task. You'll see an example of a member function that does require additional data in Section 3.5. Line 13 is commonly referred to as the function header. Every function's body is delimited by left and right braces ({ and }), as in lines 14 and 16.

The body of a function contains statements that perform the function's task. In this case, member function displayMessage contains one statement (line 15) that displays the message "Welcome to the Grade Book!". After this statement executes, the function has completed its task.

Common Programming Error 3.2

Returning a value from a function whose return type has been declared void is a compilation error.


Common Programming Error 3.3

Defining a function inside another function is a syntax error.


Testing Class GradeBook

Next, we'd like to use class GradeBook in a program. As you learned in Chapter 2, function main (lines 20–25) begins the execution of every program.

In this program, we'd like to call class GradeBook's displayMessage member function to display the welcome message. Typically, you cannot call a member function of a class until you create an object of that class. (As you'll see in Section 10.7, static member functions are an exception.) Line 22 creates an object of class GradeBook called myGradeBook. Note that the variable's type is GradeBook—the class we defined in lines 9–17. When we declare variables of type int, as we did in Chapter 2, the compiler knows what int is—it's a fundamental type. In line 22, however, the compiler does not automatically know what type GradeBook is—it's a user-defined type. We tell the compiler what GradeBook is by including the class definition (lines 9–17). If we omitted these lines, the compiler would issue an error message (such as "'GradeBook': undeclared identifier" in Microsoft Visual C++ or "'GradeBook': undeclared" in GNU C++). Each class you create becomes a new type that can be used to create objects. You can define new class types as needed; this is one reason why C++ is known as an extensible language.

Line 23 calls the member function displayMessage (defined in lines 13–16) using variable myGradeBook followed by the dot operator (.), the function name displayMessage and an empty set of parentheses. This call causes the displayMessage function to perform its task. At the beginning of line 23, "myGradeBook." indicates that main should use the GradeBook object that was created in line 22. The empty parentheses in line 13 indicate that member function displayMessage does not require additional data to perform its task. (In Section 3.5, you'll see how to pass data to a function.) When displayMessage completes its task, function main continues executing in line 24, which indicates that main performed its tasks successfully. This is the end of main, so the program terminates.

UML Class Diagram for Class GradeBook

In the UML, each class is modeled in a UML class diagram as a rectangle with three compartments. Figure 3.2 presents a class diagram for class GradeBook (Fig. 3.1). The top compartment contains the class's name centered horizontally and in boldface type. The middle compartment contains the class's attributes, which correspond to data members in C++. This compartment is currently empty, because class GradeBook does not have any attributes. (Section 3.6 presents a version of class GradeBook with an attribute.) The bottom compartment contains the class's operations, which correspond to member functions in C++. The UML models operations by listing the operation name followed by a set of parentheses. Class GradeBook has only one member function, displayMessage, so the bottom compartment of Fig. 3.2 lists one operation with this name. Member function displayMessage does not require additional information to perform its tasks, so the parentheses following displayMessage in the class diagram are empty, just as they are in the member function's header in line 13 of Fig. 3.1. The plus sign (+) in front of the operation name indicates that displayMessage is a public operation in the UML (i.e., a public member function in C++).

Fig. 3.2. UML class diagram indicating that class GradeBook has a public displayMessage operation.