Activity 6-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 write the Loan struct using a class:

 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.

// P62.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 l);

int main( )
{
Loan loan1;
float monthly_payment;

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

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

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

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

monthly_payment  = payment(loan1);

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

return 0;
}

float payment(Loan l)
{
l.rate = l.rate/1200;  // To convert % yearly rate to monthly fraction
return l.amount*l.rate*(  pow( (l.rate+1), l.term)/ (pow( (l.rate+1), l.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 (ID, amount, rate, and term) are all listed under the public section and there is no private section in the class definition.  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 in the main or any other functions that are not included in the class definition.  They are private members of the class and can only be access 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 P61.cpp, the program no longer works.  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.  This member function only accesses the data members and will not modify them. These types of functions are called accessor functions.  On the other hand we may have a function that modifies the data member or assigns values to them.  These 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.  So, for now, we need three functions.

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

These functions should be included in the public part of the class definition (where we have left two 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.  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 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;

Then, you will call the set as:
laon1.set( );

in the main function to initialize its data members.  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.

// P62a.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 6.2
Complete program P62.cpp by defining the member functions display and payment for 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

.....

Exercise 6.3
Modify the class loan and include the monthly_payment as a data member in that class.  Also, add a new function called add_loans, defined as:
float add_loans(Loan loan1, Loan loan2);  Note that you still have the payment function that computes the payment.  Since you include the monthly_payment as a member, instead of returning a value from the function, you directly set the value for monthly_payment in that function.  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.  Call your new program ex63.cpp.