CSCI 2170 LAB 6
C++ Classes

Objectives:
To introduce data encapsulation and information hiding
To introduce Object-oriented programming
To introduce the C++ class
To become familiar with C++ class syntax
CREATE ANSWER SHEET for LAB 6

In this laboratory assignment we will consider the following:

A.  Object-Oriented Programming
B.  Data Encapsulation
C.  C++ Classes
D.  C++ Class Syntax

 
 
 

Previously, we have viewed software development using functions operating on data (or structured programming). The emphasis was creating the functions. Beginning In this lab, we will place an emphasis upon the data and the associated operations that are performed upon the data. This approach to software development is called object-oriented programming (OOP).
 
 

A. Object-Oriented Programming

In the OOP approach, software objects (often called abstract data types) are used.  An object is a self-contained computing entity with its own data and its associated operations.  In real life, we deal with physical objects all the time.  When we sit in our chair (an object) at our desk (an object), we might consult our calendar (an object) to see what we must do today.  Then we might make a few calls using our phone (an object) after consulting our phone book (an object) to look up numbers and so on.

Object-oriented programming (OOP) mimics real life situations by building software using software objects.  The idea is to use software to model objects that closely correspond to real objects in the application.  Thus in our example above, we could visualize both the calendar and the phone book and possibly the desk as software objects.  Probably "today" would be a date object as well.

In the object-oriented approach to programming, a problem is decomposed into a well-defined set of objects that can be used to model  the application.  Once the objects are determined, consideration is given to exactly what data each will encapsulate(represent) and what operations are associated with the data.  Finally the relationships among the objects are established.
 
 

NOTE: For each of the following exercises, indicate answers on the answer sheet.
Exercise 11 will produce a log file, lab6ex11.log, that you will submit for grading (along with AnswerSheet6.pdf).


Exercise 1: Describe the difference between structured programming and object-oriented programming.


According to Wang [1], OOP has several advantages:
Simplicity:  Because software objects model real world objects in the application domain, the complexity of the program is reduced and the program structure is more clear and simple.

Reusability:  Objects can be reused in different programs.  A table-building object, for instance, can be used in any program that requires a table of some sort.  Thus, programs can be built from prefabricated and pretested components in a fraction of the time required to build new programs from scratch.

Maintainability:  Objects can be maintained separately, making locating and fixing problems and adding "bells and whistles" easy.

Several languages have been developed which are OOP languages.  One such language is Smalltalk.  It is considered to be a pure object-oriented language, a language in which everything is an object.  All actions in a pure object-oriented language are produced by passing messages. A message is a request sent to an object to perform an operation on its data.  Other languages like C++ are called hybrid languages because they support a combination of object-oriented and traditional structured programming. Our usage of C++ up to this point has concentrated upon the structured aspect of C++.

C++ was designed by Bjarne Stroustrup of AT&T Bell Labs in the early 1980s.  It was designed to incorporate the object-oriented paradigm into the C programming language.  C++ has become a predominant OOP language because it provides a well-designed set of language constructs which fully support OOP programming.  Secondly, it is an extension of the popular, standardized ANSI C.


Exercise 2: Describe the difference between a pure and a hybrid programming language.  Give an example of each language.

In the next section of our closed lab, we will introduce C++ objects and start using them in our problem solving.   
 

B. Data Encapsulation

First consider a real world object that most of us use -- an automobile.  We know that each automobile is described by its make (such as GM, Ford, Honda, Toyota), model, type (such as two door, four door, sedan, SUV, van), year (when it was made by a particular manufacturer), an engine, a transmission ( either a straight shift or automatic) and so on. This set of features can be thought of as "data" features describing an automobile object. Actually, most view the engine and transmission as objects in their own right, i.e., as subobjects, but they are still data features of the automobile object. The automobile object also has certain functions or "operations" which it can perform. We can "start" the automobile; we can "drive" the automobile; we can move forward; we can move in reverse; we can stop the automobile. It doesn't matter what kind of an automobile we have, we can hopefully depend on certain basic functions and features (data) being built in.  This wrapping together of data features and functions is an example of encapsulation.  This situation is analogous to the concept of data encapsulation which we use in computing.  Using this concept we view the object which consists of the data plus the functions (also called methods or operations) on these data items as "encapsulated" or bound together in a single program unit.

The operations may require certain inputs to obtain the desired results. For example, to "start" the car, we must have it in the correct gear. We must have the correct ignition key. If we use the wrong key or don't have the automobile in the correct gear, the automobile won't start. Similarly in computing, the operations associated with an object may require certain inputs/parameters before the correct results will be obtained.


Exercise 3: A DVD player can be thought of as an example of a physical object.
a.  Name some "data items or data features" which come standard with a simple DVD player?
b.  Name some  "operations" which a simple DVD player would perform?

Exercise 4: The DVD player can be used as an example of data encapsulation.  Explain.

We consider the automobile as a machine whose internal workings are not normally visible.  When we insert the correct key in the ignition and turn it, the car starts.  What goes on inside the engine is unknown and unimportant to the driver as long as the car starts.  We use this concept in computing also.  The process of "hiding" implementation details from a higher-level module (the automobile driver in our example) is called information hiding.  When we use an object, we are normally concerned with how to interface with the object (the public interface) rather than with the internal workings of the object.  The public interface of an object is composed of the collection of functions and features which allow us to use the object.  This public interface completely defines how the object can be used (similar to a manual which comes with our automobile describing how to operate and maintain the vehicle).  The public interface to the car object includes details on "starting" the car, putting the car in "drive", and in "reverse".  Each object also has internal data and functions that are available via the private interface which is not the same as the public interface. This is like when your check engine light comes on; you look in your owners manual and are told to take the automobile to the dealer for repairs. In other words, how to "repair" the engine is not part of the public interface but is part of the private interface known by the dealer. Likewise, an object organizes data and related operations into a collective structure which can hide the internal workings of the object from public view, i.e., cannot be seen/used via the public interface.


Exercise 5: Consider the DVD player again.  Describe an operation in which information hiding is being used.  Give an operation which would be in the public interface of the DVD player.

 
 
 

C. C++ Classes

As previously described, software objects are used to closely model actual objects in a real problem to be solved.  In C++, the class construct is used to model real objects. By using the C++ class definition, the data and associated operations can be collected (encapsulated) into one unit, i.e., a class.

As an example, consider a "clock" that we might use to maintain and display the time of day. We could use this "clock" in any software in which the time of day was necessary. Of course, the "clock" consists of the data plus associated operations. Thus a clock might be viewed as:
 

data:

 
 
hour
minute
second
meridian
(in the range 1-12)
(in the range 0-59)
(in the range 0-59)
(am or pm)
operations:

 
 
setClock
displayStandard
displayMilitary

(i.e. 1:30:45 pm)
(i.e. 13:30:45)

 
 
Terminology:

instance variable -- is a variable declared as part of the class, i.e., a member variable. Each object of the class has a copy of the variable.

message -- We previously defined a message as a request sent to an object to perform some operation. For example, the remark "start" is a request/message sent to the automobile (operator). As another example, a request by you to the MTSU records office to send a transcript to a potential employer is a message, i.e., your request to MTSU is the message. MTSU is the object of the request.

method -- It is the internal implementation/representation of an object operation. For now, you can think of a method as a function. How your transcript request is handled internally by MTSU relates to what "methods" MTSU uses to process your request. For the clock example, the internal function used for "setClock" is an example of a method. If you request that a clock be set to say 1pm, then your request is a message (because it comes from a source external to the actual clock) that is acted upon by an internal method (setClock in this case with parameters 1,0,0,"pm"
     Typically a "message" and "method" have the same name. A message is a request sent by an external source to an object and the object responds by invoking a method of the same name IF that method is available via the public interface.

object -- is an instance of class. As an example of the concept of class and object, consider our automobile example. Previously we provided a generic description of all automobiles, i.e., a list of possible features such as make, model, type, year, engine, and transmission along with operations: start, drive, reverse, and stop. This is analogous to a class definition. Now if we provide the features associated with your automobile such as Ford, Escort, 2-door, 2004, 3.0 Liter, 5-speed automatic,etc. then your specific automobile is an instance/example of the automobile class.

Given a clock object, we could set our clock to say 1:30:45 pm,  by sending a request (message) to the method setClock with arguments for the hour, minute, second and whether it is am or pm.  The actual representation of the data is hidden from the user.  After setting the clock to 1:30:45pm, sending the message  displayStandard would cause the time to be displayed  in the form 1:30:45 pm.


Exercise 6: Consider a "date" (time of year as opposed to time of day).
a.   What data should be included in a date?
 
b.   What methods should be included to allow us to initialize a date, to display the date in the form month/day/year? Use the "clock" as an example to go by.

D.  C++ Class Syntax

How do we implement the "clock" using C++? This is accomplished with the C++ class construct.  Normally a class definition is separated into two sections: specification and implementation. To simplify our view, we will first give the class definition as one unit. Then we will separate our definition into two parts: specification and implementation, and we will place these in separate files. Below is the complete definition of the class called Clock given as one unit.



#include <iostream>  // this is needed because of
using namespace std; // the "cout" below.

//The Clock class definition starts here. 
// Again, given here as one unit for clarity where 
// as normally this definition would be divided 
// into two parts: specification and implementation
// and written in separate files.  

class Clock 
{ 
  private:
    //declarations of data members that are private
    int hour;          //an hour in the range 1 - 12
    int minute,        //a minute in the range 0 - 59
    int second;        //a second in the range 0 - 59
    string meridian;   //is the time AM or PM

  public: 
    // publically accessible methods, i.e., the public interface 

    //Set the clock to the specified time 
    void setClock (int h, int m, int s, string mer)
    {
       hour = h;
       minute = m;
       second = s; 
       meridian = mer;
    }

    //Display the time in standard notation
    void displayStandard()
    {
      cout << hour<<':'<<minute<<':'<<second<<' ' << meridian ;
    }

    //Display the time in military notation
    void displayMilitary()
    {
      int militaryHour = hour;
  
      //if it is pm and it isn't 12:00 noon, then add 
      //12 hours to the time
      if (meridian == "PM" && hour != 12)
          militaryHour += 12;

      //if it is 12:00 midnight, then subtract 12 hours
      if (meridian == "AM" && hour == 12)
          militaryHour -= 12;

      cout << militaryHour << ':' << minute <<  ':' << second;		  
    }

};
//The Clock class definition ends with the closing brace and semicolon.


As you can see, the class definition begins with the line with the C++ reserved word class and consists of everything between the opening brace, {, up to and including the semicolon after the closing brace, }.  This definition includes a public and a private section.  The public section describes the public interface of the class (remember the car manual).  The public interface includes variables, types, constants, and methods (functions) that a programmer needs to know to use the class.  The private section includes variables, constants, data types, and methods (functions) which are to be hidden (not to be used) by other program components except those in the class definition.  Whether in the public or private section, variables and constants are referred to as data members and functions are referred to as methods.


As previously noted, the data and method prototypes for a class are normally placed in a .h file and is included in appropriate program files when the class definition is used. The implementation of the methods is usually placed in a .cpp file.

In the above example, for clarity both were placed in one file/block of code. We will now change this by dividing the "clock" class definition into the specification and implementation files. What follows is the clock.h file.



#include <iostream>  // this is needed because of
using namespace std; // the "string" data type below.

//The Clock class SPECIFICATION starts here. 
class Clock 
{ 
  private:
    //declarations of data members that are private
    int hour;          //an hour in the range 1 - 12
    int minute;        //a minute in the range 0 - 59
    int second;        //a second in the range 0 - 59
    string meridian;   //is the time AM or PM

public: 
    // publically accessible methods,i.e., public interface 

    //Set the clock to the specified time 
    void setClock (int h, int m, int s, string mer);
    //Display the time in standard notation
    void displayStandard();
    //Display the time in military notation
    void displayMilitary();
};


The following is the implementation portion of the class definition. It is placed in the file clock.cpp



    #include "clock.h"
    //Set the clock to the specified time 
    void Clock::setClock (int h, int m, int s, string mer)
    {
       hour = h;
       minute = m;
       second = s; 
       meridian = mer;
    }

    //Display the time in standard notation
    void Clock::displayStandard()
    {
      cout << hour<<':'<<minute<<':'<<second<<' ' << meridian ;
    }

    //Display the time in military notation
    void Clock::displayMilitary()
    {
      int militaryHour = hour;
  
      //if it is pm and it isn't 12:00 noon, then add 
      //12 hours to the time
      if (meridian == "PM" && hour != 12)
          militaryHour += 12;

      //if it is 12:00 midnight, then subtract 12 hours
      if (meridian == "AM" && hour == 12)
          militaryHour -= 12;

      cout << militaryHour << ':' << minute <<  ':' << second;
    }



The "clock.h" file can be included in any program file with the #include directive:

#include "clock.h"

The ".h" file needs to be included in any main program that utilizes the clock class.  The implementation section of the clock class should be placed in a different ".cpp" file other than the file containing the main function.  Thus both the clock implementation file and the main function file must have the #include "clock.h" directive.  However, if an application program includes this header file more than once, the compiler issues an error message that there is an attempt to redefine a type.  We can avoid this problem/error, by surrounding the clock specification definition with preprocessor-directives as follows:



//Eliminate the problem of multiple inclusions 
#ifndef CLOCK_H
#define CLOCK_H
    
//the class definitions come here
.
.
.
#endif


Before clock.h is included initially, the constant CLOCK_H is not defined.  Thus the #define directive causes the constant CLOCK_H and the class Clock to become defined.  For subsequent inclusions, the preprocessor notes that CLOCK_H has a definition and does not pass the remainder of the file to the compiler so the Clock class is not redefined.


Exercise 7: Write the specification section of  a Date class.  You have already decided what data and methods should be included in this class in Exercise 6.   Type this into a file called date.h in your account. Remember you are only giving the prototype for each method and not the implementation! Use the Clock class specification definition found in the file clock.h as an example to follow.

In addition to the specification section, an implementation section must be developed which defines each function included in the class definition.  As noted above, the implementation section for a class is usually placed in a separate file. You can find our Clock class implementation file in clock.cpp.


Exercise 8: You should load the file,  clock.cpp, from the 2170 account and examine it now.

The implementation of the setClock function is as follows:



//Function:  setClock() 
//Purpose:   This function assigns the time specified by the user.
//           No error checking is done to check for illegal values.
//           Arguments include the hour (h), minute (m), second(s)
//           and meridian (am or pm).
void Clock::setClock(int h, int m, int s, string mer) 
                     //IN      IN      IN     IN
{
    //hr, min, sec and amPm are private data members
    hour = h;
    minute = m;
    second = s;
    meridian = mer;
}


As you can see from this method definition, we are just defining the function (method), setClock, which appears in the clock.cpp file. Note that the method has direct access to the private data members of the class such as hour, minute, second, and meridian. Methods outside the class implementation file do not have this access! One difference between methods in the implementation file and functions outside the implementation file is the function heading.  Consider the setClock heading.

void Clock::setClock(int h, int m, int s, string mer)

The operator :: is used and is preceded by the name of the class in which setClock is a method. The operator :: is called the scope resolution operator.  It is possible for several different classes to have member functions with the same name.  The scope resolution operator is like the dot operator that was introduced (and we will see again shortly) in the lab on structs.  The scope resolution operator is used to tell the compiler to what class a member function belongs.  Thus when Clock:: precedes the name of the function setClock, we automatically know that setClock is a member function in the class Clock.


Exercise 9: Write the implementation section for the date object which was defined in Exercise 6 and 7.  Place this in the file date.cpp.

Now, how can we use this class specification and implementation in a program? Consider the following main program that uses our Clock class.



#include <iostream>
#include "clock.h"
using namespace std;

int main()
{
    //Declare two Clock objects
    Clock myClock, newClock;

    //Set the time of myClock to 12:45:30 am.
    myClock.setClock(12, 45, 30, "am");

    //Set the time of the newClock object to 2:15:30 pm.
    newClock.setClock (2, 15, 30, "pm"); 

    //Display the time of myClock in both standard and
    //military format
    cout << "The time on the Digital Clock (in standard form) is: "
    myClock.displayStandard(); 
    
    cout << "\nThe time in military format is: ";
    myClock.displayMilitary(); 
    
    //Set the two times to the same time
    myClock = newClock;

    //Display the time of myClock in standard time  
    cout << "The time on the Digital Clock (in standard form) is: "
    myClock.displayStandard(); 
 
    return 0; 
}


Notice that the dot operator is used to select a particular member function (method) to invoke.  This is how "messages" are passed to an object in C++.  Thus,

myClock.setClock(12,45,30,"am");
sends the setClock message to the object myClock.

In the above function, the assignment statement:

myClock = newClock;
This line is valid and copies all data fields from the object newClock to the object myClock.  It is valid and accomplishes what we desire in this example because we have simple data types making up the two objects.

Note that nowhere in our main function do we try to access the data variables hour, second, minute, and meridian which were defined in the Clock class.  In fact, we could not do so because these data members were placed in the private section of the class which means that only members of the class can access them.  Thus we could not incorporate the following statements in the main function:

//This is an invalid member access
myClock.hour = 2;

Exercise 10:The above example was a very simple example of a main program utilizing the Clock class.  For a slightly more complicated example of a main program utilizing the Clock class, load the file clock_main.cpp from the 2170 account to your account.  Both the main function and the implementation functions for the Clock class must be compiled.  Since they are in separate files, a slight variation of the compilation command is required.  To compile this program, type
c++ clock_main.cpp clock.cpp -o inlab6a
Run the program (the executable  is contained in inlab6a).  Read the program and make sure you understand the code.  What does the program do?  
Exercise 11:Write a simple main program which utilizes your Date class and place the program in date_main.cpp .  The program should create a birth date and a graduation date containing your birthday and a tentative date for your graduation from MTSU.  Print the dates in the form MM/DD/YY using your display Date method as described in exercises 6 and 7 above.

You are to hand in the source program listings of the three files you created, compilation results, and a sample run of the program. The following UNIX commands will let you submit what is required:

            $ script lab6ex11.log
            $ pr -n -t -e4 date.h date.cpp date_main.cpp
            $ c++ date_main.cpp date.cpp -o lab6
            $ lab6
            $ exit
            $ handin "lab6log" lab6ex11.log
(Be sure to exit the script session before trying to submit the log!)

----- End of Lab 6 - C++ Classes -----
Complete the Exercises on the Answer Sheet
Submit the completed (final) Lab 6 Answer Sheet (AnswerSheet6.pdf) using the GUS web site with AssignmentID "lab6ans".

 
 
 
References

1.  Wang, Paul.  C++ with Object-Oriented Programming, PWS Publishing Company, 1994.

 
 
Return to the top of this lab
Return to the link page for all 2170 labs