Activity 11-2 - Classes - A New Type Definition
A Package of Values and Functions of Different Types



A class is a data type whose variables are objects.  In the previous activity, you learned about the struct. A struct can hold variables of different types, but cannot hold any function.  However, in a similar way that you created different structures of a particular type, you can use a class definition to create many instances of a class. A class is usually defined in a similar fashion as a struct. However, in general, a class has two parts; the public and the private parts.

Suppose we want to rewrite the Loan data typy by using a class construct instead of the previous struct construct. The following table describes the differences between the two type definitions.
Class Loan
Struct Loan
class Loan 
{
        public:
            int ID;  // assume an unique integer between 1111-9999
            float amount; // $ amount of the loan
            float rate; // annual interest rate
            int term;  // number of months, length of the loan
};
struct Loan  // Loan is called structure tag
{
       int ID;  // assume an unique integer between 1111-9999
       float amount; // $ amount of the loan
      float rate; // annual interest rate
      int term;  // number of months, length of the loan
};

Actually, at this stage, these two are almost identical.  They may go through two different sets of steps in the machine, but will come out with the same end result.

// P112.cpp - This program uses a class for a loan, initializes it from the keyboard, then
// displays the class

#include<iostream>
#include<cmath>
using namespace std;

class Loan  // loan class definition
{
    public:
       int ID;  // assume an unique integer between 1111-9999
       float amount; // $ amount of the loan
      float rate; // annual interest rate
      int term;  // number of months, length of the loan
};

float payment(Loan aloan);

int main( )
{
      Loan loan1;
      float monthly_payment;

      // Initialize the loan1 object
      cout << "Enter the ID of this loan \n";
      cin >> loan1.ID;     //reading the ID of loan1

      cout << "Enter the amount of this loan \n";
      cin >> loan1.amount;    //reading the amount of loan1

      cout << "Enter the annual interest rate of this loan (in %) \n";
      cin >> loan1.rate;         //reading the rate of loan1

      cout << "Enter the term (number of months, length of the loan) \n";
      cin >> loan1.term;      //reading the term of loan1

      monthly_payment  = payment(loan1);    //call the payment function on loan1 using the procedural approach

      cout << "The monthly payment for loan " << loan1.ID << " is: " << monthly_payment << endl;

      return 0;
}

// function payment(Loan loan) define separately as in procedural approach
float payment(Loan aloan)
{
      aloan.rate = aloan.rate/1200;  // To convert % yearly rate to monthly fraction
      return aloan.amount*aloan.rate*(  pow( (aloan.rate+1), aloan.term)/ (pow( (aloan.rate+1), aloan.term) - 1) );
}

The reason that the class and struct definitions are the same is because we haven't used a function yet.  As soon as we decide to include a function in our data type, a struct is no longer a possibility, it can't do it.  You may also have noticed that the data members of the class (i.e. ID, amount, rate, and term) are all listed under the public section and there is no private section in the class definition. Is this possible? Yes, it is possible. Is this desirable? NO, it is NOT desirable. In general, we want the data members to go under the private section of the class and that is where the trouble begins. Why? Once you put the variable members under private, you no longer can access them directly from the main (as we have done so far), neither can any other function that is not included in the class definition. They are private members of the class and can only be accessed by the functions defined in the private or public section of the class. Suppose we decide to rewrite the Loan class again to meet this requirement:

class Loan  // Loan is called structure tag
{
    public:
                  ??
                  ??
   private:
       int ID;  // assume an unique integer between 1111-9999
       float amount; // $ amount of the loan
      float rate; // annual interest rate
      int term;  // number of months, length of the loan
};

If we make this change in P111.cpp, the program no longer works. The reason why the program no longer works is due to the fact that the variables ID, amount, rate and termI of the loan cannot be accessed directly since they are in the rpivate area accessible only to the member function of the class (in other words loan1.amount will not read from or write into the variable amount of the loan unless there is a member function in the class that let you do that!). Therefore we want the payment function be able to access the private members of the class. In order for the payment function to be able to access the private data members, it must be included in the definition of the class, i.e., it has to become a member function. The member function that only access the data members and will not modify them are called accessor functions. On the other hand we may define functions that modifie the data members or assign values to them.  These functions are called mutator functions. Also, we no longer can access the data members in the main to display them, thus, we need another member function to do the display. In conclusion, for now, we need to define at least three functions in the class:

void set( )
// This function will initialize the data members of an object

float payment( )
// This function will compute the monthly payment for a loan object

void display()
// This function will display a loan object

Since avery program must be able to access these function in order to access the data mmbers (that are kept private), these functions should be included in the public part of the class. We will insert these functions definition where we inserted the question marks.

class Loan  // Loan is called structure tag
{
    public:
         void set( );
         float payment( );
         void display( );
   private:
       int ID;  // assume an unique integer between 1111-9999
       float amount; // $ amount of the loan
      float rate; // annual interest rate
      int term;  // number of months, length of the loan
 };

The next thing we need to do is to write these functions (define them or implement them).  We will use the scope resolution operator (::) to distinguish between a member function and a (regular) function.  For example function set is now a member function of class Loan.  Thus, we use :: to identify it.

void Loan::set( )
{
       // Initialize the loan1 object
      cout << "Enter the ID of this loan \n";
      cin >> ID;

      cout << "Enter the amount of this loan \n";
      cin >> amount;

      cout << "Enter the annual interest rate of this loan (in %) \n";
      cin >> rate;

      cout << "Enter the term (number of months, length of the loan) \n";
      cin >> term;
}

Note that we don't need to specify whose data members we are initializing because the function will be called with a dot operator, as any_object.set( ), which tells the compiler that it is the data members of the any_object that you are initializing. For example, to call the set function in the main, we first define an object of type Loan, let's say:

Loan loan1; //create an object of type Loan and call it loan1

Then, to initialize data members of the object loan1, in the main function you will call the set function as:

loan1.set( ); //call the member fucntion set for the object loan1 to initialize the values of the data members of loan1

To initialize the data members of loan2, you need to go through a similar process.

Here is a driver that can be used to test the set function.

// P112a.cpp - This program is a driver written to demonstrate how the set function works.
#include<iostream>
using namespace std;

class Loan  // Loan is called structure tag
{
    public:
         void set( );
         float payment( );
         void display( );
   private:
       int ID;  // assume an unique integer between 1111-9999
       float amount; // $ amount of the loan
      float rate; // annual interest rate
      int term;  // number of months, length of the loan
 };

int main( )
{
    Loan loan1;
    loan1.set( );
    return 0;
}

void Loan::set( )
{
       // Initialize the loan1 object
      cout << "Enter the ID of this loan \n";
      cin >> ID;

      cout << "Enter the amount of this loan \n";
      cin >> amount;

      cout << "Enter the annual interest rate of this loan (in %) \n";
      cin >> rate;

      cout << "Enter the term (number of months, length of the loan) \n";
      cin >> term;
}
 

Exercise 11.2
Complete program P112.cpp by defining the member functions display and payment for the class Loan. Note that the display function will display all the information about a loan, i.e.,
ID:
Amount:
Rate:
Term:
You will display the monthly payment in the main by assigning the returned value from the payment function to a variable of type float. Suppose, in the main we have declared:

.....
float p;
Loan loan1;
loan1.set( );
  .....
loan1.display( ) // will display the data members of loan1
p = loan1.payment( ) // will return the monthly payment of loan1
.....

Call this program ex112.cpp. 

Exercise 11.3
Modify the class Loan by including monthly_payment as a data member of the Loan class and by adding a new member function, called add_loans, defined as:
float add_loans(Loan loan1, Loan loan2); 
The new function, add_loans, takes two loan objects and computes the total monthly payment, i.e., the sum of monthly payments of the two loans. Note that you still have the payment function that computes the payment. Since you include the add_loans as a member function, you can directly set the value for monthly_payment in that function and call the payment function if required. Call your new program ex113.cpp.