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 functional (or procedural) oriented programming.  In this approach, software is developed by decomposing the solution to a problem into functions.  These functions represent the step-by-step procedures, called algorithms, which solve the problem.  Usually data structures (like arrays or strings) are a secondary concern and are selected after the project has been broken down into functional modules.  There are other approaches to software development.  One such approach is called object-oriented programming (OOP).
 
 
 

A. Object-Oriented Programming

In the OOP approach, software objects are used.  A software object is considered to be a self-contained computing entity with its own data and its associated operations or methods.  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 objects which 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 and what operations are needed for the data.  Finally the relationship among the objects is established.
 
 
 

NOTE: For each of the following exercises, indicate answers on the answer sheet.

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

OOP has several advantages.  Listed below are a few advantages taken from Wang [1].

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 for an object to perform one of its operations on some of its data..  Other languages like C++ are called hybrid languages because they support a combination of object-oriented and traditional procedure-oriented programming.

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 this lab, we will introduce C++ objects and start using them in our problem solving.  However, we will not truly use the object-oriented approach to programming in this class.  We will still predominantly use procedure-oriented programming and we will only use objects to represent the data structures which we will need in our applications.  We will gradually work our way from the procedural oriented approach to the object-oriented approach in this and subsequent classes.
 
 
 

B. Data Encapsulation

Consider an object most of us use -- an automobile.  We know that each automobile  has a certain model type, was built in a certain year, was made by a particular manufacturer, has a steering wheel, an ignition, is either straight shift or automatic  and so on.  This set of features can be thought of as "data" features describing an automobile object.  The automobile object also has certain functions  or "operations" which it should perform.  When we "start it", the motor is supposed to start.  When we put it in "drive", it is supposed to move forward.  When we put it in "reverse", it is supposed to go backwards.  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 data which composes the data structure and 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 and certain assumptions to obtain the desired results.  For example, to "start" the car, we assume it is in the correct gear.  Then we must insert the correct key in the ignition and turn the key to obtain the results we want--namely the automobile will start.  If we use the wrong key or don't have the car in the correct gear, the automobile won't start.  Similarly in computing, the operations which are bound with an object may have certain inputs and assumptions which must be provided before the correct results will be obtained.


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

Exercise 4: The VCR 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 machine is unknown and unimportant as long as the car starts.  We use this concept in computing also.  The process of "hiding" implementation details from a higher-level module 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 effectively.  This public interface completely defines how to use the object (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".  The internal (private) data or functions in an object are unavailable to the public.  This would be like disabling the hood release so we would not be able to access internal parts of an automobile  (which would be a good idea in some cases).  An object organizes data and related functions (methods) into a black box, which hides the internal data structures, representations, and procedures from outside view.


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

 
 
 

C. C++ Classes

As previously described, objects are used to closely model actual objects in a real problem to be solved.  In C++, the class construct is used to define an object.  Using the class, the object's data and associated operations can be collected (encapsulated) into one unit.

Consider a  "clock" object.  We might use this object to maintain and display the time of day.  We could use this object in any software in which the time of day was necessary.  Of course, the clock object consists of the data and operations(methods) associated with the data.  Thus a clock might be viewed as:
 

data:

 
 
hour
minute
second
am/pm
(in the range 1-12)
(in the range 0-59)
(in the range 0-59)
(0 if am, 1 if pm)
methods:

 
 
setClock
displayStandard
displayMilitary
incrementClock

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

 
 

We could set a clock, say to 1:30:45 pm,  by passing the method setClock arguments for the hour, minute, second and whether it is am or pm.  The actual representation of the data is hidden from the user.  Sending the message  displayStandard would cause the time to be displayed  in the form 1:30:45 pm.  Sending the message incrementClock would add one second to the clock time to make it change to 1:30:46 pm.


Exercise 6: Consider a "date" object.  We might use this object to maintain and display a date.
a.   What data should be included in a date object?
 
b.   What methods should be included to allow us to initialize a date, to display the date in the form 12/25/96, or to display the date in the form Month Day, Year?  Use the "clock" as an example to go by.   (We won't have a method to increment the date in our "date" object.)

D.  C++ Class Syntax

Now we will learn how to implement the "clock" object using C++.   This is accomplished with the C++ class construct.  The class consists of two sections of code, a definition section, and an implementation section.  Below is the definition section for a class called Clock.



//The Clock class definition starts here. 
class Clock 
{ 
public: 
    //function prototypes of member functions (methods) 

    //Set the clock to the specified time 
    void setClock (int h, int m, int s, int aOrP);

    //Display the time in standard notation
    void displayStandard();

    //Display the time in military notation
    void displayMilitary();

    //Increment the time by one second
    void incrementClock();

private:
    //declarations of data members that are private
    int hr,     //an hour in the range 1 - 12
        min,    //a minute in the range 0 - 59
        sec,    //a second in the range 0 - 59
        amPm;   //is the time AM or PM
};
//The Clock class definition ends with the closing brace and semicolon.


As you can see, the definition section begins with the line that starts 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 section 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 function prototypes that a programmer needs to know to use the class.  The private section includes variables, constants, data types, and function prototypes 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 function members.

The definition section for a class is usually placed in a .h file and is included in appropriate program files when the class definition is used.  The Clock class is in the file inlab6a.h in the 2170 account.  Copy this file to your account and examine it.  This file can be included in a program file with the #include directive:

#include "inlab6a.h"

This file will need to be included in the implementation section of the class which will be discussed next and it will also need to be included in any main program that utilizes the class.  The implementation section is usually contained in a different file other than the file containing the main function.  Thus both the implementation file and the main function file must have the #include 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.  Thus we surround the 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 inlab6a.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 definition 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 inlab6b.h in your account.  Use the definition of the Clock class in the file inlab6a.h as an example to follow.

In addition to the definition section, an implementation section must be developed which defines each function included in the class definition.  The implementation section for a class is usually placed in a separate file and the Clock class implementation can be found in the file inlab6a.cc.


Exercise 8: You should load the file,  inlab6a.cc, 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 dates.
//           Arguments include the hour (h), minute (m), second(s)
//           and aOrP (0 means am and 1 means pm).
void Clock::setClock(int h, int m, int s, int aOrP) 
                     //IN      IN      IN     IN
{
    //hr, min, sec and amPm are private data members
    hr = h;
    min = m;
    sec = s;
    amPm = aOrP;
}


As you can see from this definition, we are just defining the function (method), setClock, which appears in the definition section of the Clock class.  Note that the method has direct access to the private data members of the class.  Functions outside the implementation file do not!  The main difference between functions 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, int aOrP)

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 inlab6b.cc.

Now, how do we use this class definition and implementation in a program?  The class definition defines the interface to an object and what data should be in the object.  To declare and use objects of type Clock, consider the following simple main function:



#include <iostream>
#include "inlab6a.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, 0);

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

    //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;
 
    return 0; 
}


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

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

In the above function, notice the last line before the return statement.  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 hr, sec, and min 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.hr = 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 main6a.cc 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
aCC inlab6a.cc main6a.cc -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 main6b.cc .  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 and in the form Month Day, Year.   Turn in a printout containing a listing of the three files inlab6b.h, inlab6b.cc, and main6b.cc, a compile and a run.


Exercise 12:
Click on the following button to start a program for this exercise. A window with a new programming environment will pop up. You need to work on the textbox to do the exercise. Read and follow the instruction embedded in the program. Check the menus in the menu bar for the options available such as saving, compiling, and running. When you are done submit your program by selecting the Submit under Grade menu. When the submission is done, print the result by right clicking on the bottom window and select print.


Tutor
----- End of Lab 6 - C++ Classes -----
Complete the Exercises on the Answer Sheet
Turn in the Answer Sheet and the printouts required by the exercises.

 
 
 
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