====== Defining class GradeBook with a member function, creating a GradeBook object and calling its member function. ====== 1 2 // Define class GradeBook with a member function displayMessage; 3 // Create a GradeBook object and call its displayMessage function. 4 #include 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 * Methods of a class are called member functions. \\ * Line 11 contains the **access-specifier** label //public://. The keyword public is called an **access specifier**. \\ ====== Defining a Member Function with a Parameter ====== 1 2 // Define class GradeBook with a member function that takes a parameter; 3 // Create a GradeBook object and call its displayMessage function. 4 #include 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include // program uses C++ standard string class 10 using std::string; 11 using std::getline; 12 13 // GradeBook class definition 14 class GradeBook 15 { 16 public: 17 // function that displays a welcome message to the GradeBook user 18 void displayMessage( string courseName ) 19 { 20 cout << "Welcome to the grade book for\n" << courseName << "!" 21 << endl; 22 } // end function displayMessage 23 }; // end class GradeBook 24 25 // function main begins program execution 26 int main() 27 { 28 string nameOfCourse; // string of characters to store the course name 29 GradeBook myGradeBook; // create a GradeBook object named myGradeBook 30 31 // prompt for and input course name 32 cout << "Please enter the course name:" << endl; 33 getline( cin, nameOfCourse ); // read a course name with blanks 34 cout << endl; // output a blank line 35 36 // call myGradeBook's displayMessage function 37 // and pass nameOfCourse as an argument 38 myGradeBook.displayMessage( nameOfCourse ); 39 return 0; // indicate successful termination 40 } // end main * Line 28 creates a variable of type string called nameOfCourse that will be used to store the course name entered by the user. A string is actually an object of the C++ Standard Library class string. This class is defined in header file , and the name string, like cout, belongs to namespace std. To enable line 28 to compile, line 9 includes the header file. Note that the using declaration in line 10 allows us to simply write string in line 28 rather than std::string. \\ * Line 33 reads the name from the user and assigns it to the nameOfCourse variable, using the library function getline to perform the input.\\ * When cin is used with the stream extraction operator, it reads characters until the first white-space character is reached. In this example, we'd like the user to type the complete course name and press Enter to submit it to the program, and we'd like to store the entire course name in the string variable nameOfCourse. \\ * The function call getline( cin, nameOfCourse ) in line 33 reads characters (including the space characters that separate the words in the input) from the standard input stream object cin (i.e., the keyboard) until the newline character is encountered, places the characters in the string variable nameOfCourse and discards the newline character. Note that when you press Enter while typing program input, a newline is inserted in the input stream. Also note that the header file must be included in the program to use function getline and that the name getline belongs to namespace std. \\ ====== Data Members, set Functions and get Functions ====== 1 2 // Define class GradeBook that contains a courseName data member 3 // and member functions to set and get its value; 4 // Create and manipulate a GradeBook object with these functions. 5 #include 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 10 #include // program uses C++ standard string class 11 using std::string; 12 using std::getline; 13 14 // GradeBook class definition 15 class GradeBook 16 { 17 public: 18 // function that sets the course name 19 void setCourseName( string name ) 20 { 21 courseName = name; // store the course name in the object 22 } // end function setCourseName 23 24 // function that gets the course name 25 string getCourseName() 26 { 27 return courseName; // return the object's courseName 28 } // end function getCourseName 29 30 // function that displays a welcome message 31 void displayMessage() 32 { 33 // this statement calls getCourseName to get the 34 // name of the course this GradeBook represents 35 cout << "Welcome to the grade book for\n" << getCourseName() << "!" 36 << endl; 37 } // end function displayMessage 38 private: 39 string courseName; // course name for this GradeBook 40 }; // end class GradeBook 41 42 // function main begins program execution 43 int main() 44 { 45 string nameOfCourse; // string of characters to store the course name 46 GradeBook myGradeBook; // create a GradeBook object named myGradeBook 47 48 // display initial value of courseName 49 cout << "Initial course name is: " << myGradeBook.getCourseName() 50 << endl; 51 52 // prompt for, input and set course name 53 cout << "\nPlease enter the course name:" << endl; 54 getline( cin, nameOfCourse ); // read a course name with blanks 55 myGradeBook.setCourseName( nameOfCourse ); // set the course name 56 57 cout << endl; // outputs a blank line 58 myGradeBook.displayMessage(); // display message with new course name 59 return 0; // indicate successful termination 60 } // end main * Declaring data members with access specifier private is known as data hiding. \\ * Note that set functions are also sometimes called mutators (because they mutate, or change, values), and get functions are also sometimes called accessors (because they access values). \\ ====== Initializing Objects with Constructors ====== What if you want to provide a course name when you create a GradeBook object? Each class you declare can provide a **constructor** that can be used to initialize an object of the class when the object is created. A constructor is a special member function that must be defined with the same name as the class, so that the compiler can distinguish it from the class's other member functions. An important difference between constructors and other functions is that constructors cannot return values, so they cannot specify a return type (not even void). Normally, constructors are declared public.\\ 1 // Fig. 3.7: fig03_07.cpp 2 // Instantiating multiple objects of the GradeBook class and using 3 // the GradeBook constructor to specify the course name 4 // when each GradeBook object is created. 5 #include 6 using std::cout; 7 using std::endl; 8 9 #include // program uses C++ standard string class 10 using std::string; 11 12 // GradeBook class definition 13 class GradeBook 14 { 15 public: 16 // constructor initializes courseName with string supplied as argument 17 GradeBook( string name ) 18 { 19 setCourseName( name ); // call set function to initialize courseName 20 } // end GradeBook constructor 21 22 // function to set the course name 23 void setCourseName( string name ) 24 { 25 courseName = name; // store the course name in the object 26 } // end function setCourseName 27 28 // function to get the course name 29 string getCourseName() 30 { 31 return courseName; // return object's courseName 32 } // end function getCourseName 33 34 // display a welcome message to the GradeBook user 35 void displayMessage() 36 { 37 // call getCourseName to get the courseName 38 cout << "Welcome to the grade book for\n" << getCourseName() 39 << "!" << endl; 40 } // end function displayMessage 41 private: 42 string courseName; // course name for this GradeBook 43 }; // end class GradeBook 44 45 // function main begins program execution 46 int main() 47 { 48 // create two GradeBook objects 49 GradeBook gradeBook1( "CS101 Introduction to C++ Programming" ); 50 GradeBook gradeBook2( "CS102 Data Structures in C++" ); 51 52 // display initial value of courseName for each GradeBook 53 cout << "gradeBook1 created for course: " << gradeBook1.getCourseName() 54 << "\ngradeBook2 created for course: " << gradeBook2.getCourseName() 55 << endl; 56 return 0; // indicate successful termination 57 } // end main Any constructor that takes no arguments is called a default constructor. A class gets a default constructor in one of two ways: \\ - The compiler implicitly creates a default constructor in a class that does not define a constructor. Such a default constructor does not initialize the class's data members, but does call the default constructor for each data member that is an object of another class. \\ - The programmer explicitly defines a constructor that takes no arguments. Such a default constructor will perform the initialization specified by the programmer and will call the default constructor for each data member that is an object of another class. \\ ====== Placing a Class in a Separate File for Reusability ====== Each of the previous examples in the chapter consists of a single **.cpp** file, also known as a source-code file, that contains a GradeBook class definition and a main function. When building an object-oriented C++ program, it is customary to define reusable source code (such as a class) in a file that by convention has a **.h** filename extension known as a **header file**. Programs use #include preprocessor directives to include header files and take advantage of reusable software components, such as type string provided in the C++ Standard Library and user-defined types like class GradeBook.\\ ===== GradeBook class definition ===== 1 // GradeBook.h 2 // GradeBook class definition in a separate file from main. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include // class GradeBook uses C++ standard string class 8 using std::string; 9 10 // GradeBook class definition 11 class GradeBook 12 { 13 public: 14 // constructor initializes courseName with string supplied as argument 15 GradeBook( string name ) 16 { 17 setCourseName( name ); // call set function to initialize courseName 18 } // end GradeBook constructor 19 20 // function to set the course name 21 void setCourseName( string name ) 22 { 23 courseName = name; // store the course name in the object 24 } // end function setCourseName 25 26 // function to get the course name 27 string getCourseName() 28 { 29 return courseName; // return object's courseName 30 } // end function getCourseName 31 32 // display a welcome message to the GradeBook user 33 void displayMessage() 34 { 35 // call getCourseName to get the courseName 36 cout << "Welcome to the grade book for\n" << getCourseName() 37 << "!" << endl; 38 } // end function displayMessage 39 private: 40 string courseName; // course name for this GradeBook 41 }; // end class GradeBook * See that in the constructor declaration we call setCourseName function, the reason for this is simple. We can put some kind of validation into this function and don't worry about it in the constructor. Modular code. ===== Including class GradeBook from file GradeBook.h for use in main ===== 1 // fig03_10.cpp 2 // Including class GradeBook from file GradeBook.h for use in main. 3 #include 4 using std::cout; 5 using std::endl; 6 7 #include "GradeBook.h" // include definition of class GradeBook 8 9 // function main begins program execution 10 int main() 11 { 12 // create two GradeBook objects 13 GradeBook gradeBook1( "CS101 Introduction to C++ Programming" ); 14 GradeBook gradeBook2( "CS102 Data Structures in C++" ); 15 16 // display initial value of courseName for each GradeBook 17 cout << "gradeBook1 created for course: " << gradeBook1.getCourseName() 18 << "\ngradeBook2 created for course: " << gradeBook2.getCourseName() 19 << endl; 20 return 0; // indicate successful termination 21 } // end main * To ensure that the preprocessor can locate header files correctly, #include preprocessor directives should place the names of user-defined header files in quotes (e.g., "GradeBook.h") and place the names of C++ Standard Library header files in angle brackets (e.g., ). ====== Separating Interface from Implementation ====== * The interface of a class describes what services a class's clients can use and how to request those services, but not how the class carries out the services. A class's interface consists of the class's public member functions (also known as the class's public services). For example, class GradeBook's interface contains a constructor and member functions setCourseName, getCourseName and displayMessage. GradeBook's clients (e.g., main) use these functions to request the class's services. As you will soon see, you can specify a class's interface by writing a class definition that lists only the member function names, return types and parameter types. \\ * In our prior examples, each class definition contained the complete definitions of the class's public member functions and the declarations of its private data members. However, it is better software engineering to define member functions outside the class definition, so that their implementation details can be hidden from the client code. \\ * The program separates class GradeBook's interface from its implementation by s//plitting the class definition into two files//. the header file GradeBook.h in which **class GradeBook is defined**, and the source-code file GradeBook.cpp in which **GradeBook's member functions are defined**. By convention, member-function definitions are placed in a source-code file of the same base name (e.g., GradeBook) as the class's header file but with a .cpp filename extension. \\ * A **function prototype** is a declaration of a function that tells the compiler the function's name, its return type and the types of its parameters. Note that the header file still specifies the class's **private data member** as well. \\ * These function prototypes are the same as the corresponding function headers in the previous example, except that the parameter names (which are optional in prototypes) are not included and each function prototype must end with a semicolon. \\ ===== GradeBook class definition containing function prototypes that specify the interface of the class. ===== 1 // GradeBook.h 2 // GradeBook class definition. This file presents GradeBook's public 3 // interface without revealing the implementations of GradeBook's member 4 // functions, which are defined in GradeBook.cpp. 5 #include // class GradeBook uses C++ standard string class 6 using std::string; 7 8 // GradeBook class definition 9 class GradeBook 10 { 11 public: 12 GradeBook( string ); // constructor that initializes courseName 13 void setCourseName( string ); // function that sets the course name 14 string getCourseName(); // function that gets the course name 15 void displayMessage(); // function that displays a welcome message 16 private: 17 string courseName; // course name for this GradeBook 18 }; // end class GradeBook ===== Defining Member Functions in a Separate Source-Code File ===== * Notice that each member function name in the function headers (lines 11, 17, 23 and 29) is preceded by the class name and ::, which is known as the binary scope resolution operator. \\ * This "ties" each member function to the (now separate) GradeBook class definition, which declares the class's member functions and data members. Without "GradeBook::" preceding each function name, these functions would not be recognized by the compiler as member functions of class GradeBookthe compiler would consider them "free" or "loose" functions, like main. Such functions cannot access GradeBook's private data or call the class's member functions, without specifying an object. So, the compiler would not be able to compile these functions. \\ 1 // GradeBook.cpp 2 // GradeBook member-function definitions. This file contains 3 // implementations of the member functions prototyped in GradeBook.h. 4 #include 5 using std::cout; 6 using std::endl; 7 8 #include "GradeBook.h" // include definition of class GradeBook 9 10 // constructor initializes courseName with string supplied as argument 11 GradeBook::GradeBook( string name ) 12 { 13 setCourseName( name ); // call set function to initialize courseName 14 } // end GradeBook constructor 15 16 // function to set the course name 17 void GradeBook::setCourseName( string name ) 18 { 19 courseName = name; // store the course name in the object 20 } // end function setCourseName 21 22 // function to get the course name 23 string GradeBook::getCourseName() 24 { 25 return courseName; // return object's courseName 26 } // end function getCourseName 27 28 // display a welcome message to the GradeBook user 29 void GradeBook::displayMessage() 30 { 31 // call getCourseName to get the courseName 32 cout << "Welcome to the grade book for\n" << getCourseName() 33 << "!" << endl; 34 } // end function displayMessage ===== GradeBook class demonstration after separating its interface from its implementation. ===== 1 // fig03_13.cpp 2 // GradeBook class demonstration after separating 3 // its interface from its implementation. 4 #include 5 using std::cout; 6 using std::endl; 7 8 #include "GradeBook.h" // include definition of class GradeBook 9 10 // function main begins program execution 11 int main() 12 { 13 // create two GradeBook objects 14 GradeBook gradeBook1( "CS101 Introduction to C++ Programming" ); 15 GradeBook gradeBook2( "CS102 Data Structures in C++" ); 16 17 // display initial value of courseName for each GradeBook 18 cout << "gradeBook1 created for course: " << gradeBook1.getCourseName() 19 << "\ngradeBook2 created for course: " << gradeBook2.getCourseName() 20 << endl; 21 return 0; // indicate successful termination 22 } // end main * Before executing this program, the source-code files in previous two snippets must both be compiled, then linked together that is, the member-function calls in the client code need to be tied to the implementations of the class's member functionsa job performed by the linker.\\