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
{ 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.