A Journey to understanding and implementation of a class

The following program asks users to input the amount of money for two people.  The money for each person is entered in two parts, the dollars part and the cents part.  The program then displays each money and also sums them up and will display the result which is also is another money.  We use a couple of functions, one for display purpose and the other to compute the sum.

// Program plain_money.C
// Rahman Tashakkori - CS1440
// A program that asks for your_money and my_money and then displays them
// and, also displays their sum.  In this program a money is made up two
// parts: the dollars part and the cents part both as integers.

#include <iostream>
using namespace std;

void display_money(int d, int c); 
void add(int y_d, int y_c, int m_d, int m_c, int& s_d, int& s_c);

int main( )
{
    int my_money_d, my_money_c;      // The dollars and cents for my money
    int your_money_d, your_money_c;  // The dollars and cents for your money
    int sum_money_d, sum_money_c;      // The dollars and cents for the sum

    cout << "Enter the dollar part of your money ";
    cin >> your_money_d;
    cout << endl;
    cout << "Enter the cent part of your money ";
    cin >> your_money_c;
    cout << endl;
    display_money(your_money_d,your_money_c);

    cout << "Enter the dollar part of my money ";
    cin >> my_money_d;
    cout << endl;
    cout << "Enter the cent part of my money ";
    cin >> my_money_c;
    cout << endl;
    display_money(my_money_d, my_money_c);

    add(your_money_d, your_money_c, my_money_d, my_money_c, sum_money_d, sum_mon
    cout << "The sum was: ";
    display_money(sum_money_d, sum_money_c);

    return 0;
}

void display_money(int d, int c)
{
    cout << "$" << d << ".";
    if(c < 10)
        cout << "0";
    cout << c << endl;
    return;
}

void add(int y_d, int y_c, int m_d, int m_c, int& s_d, int& s_c)

{
    s_d = y_d + m_d;         //Sum the dollars up

    s_c = y_c + m_c;         //Sum the cents up

    s_d = s_d + s_c/100;  // when cents > 100, add 1 to dollar for
                                      // each 100 cents to dollars

     s_c = s_c%100;  // count for those cents that are converted to dollars
}

Struct
Okay, the above program worked.  But, it seems like a great idea, if we could somehow define a variable of type money that keeps both the dollars and cents part of each money.  No, not like a double value, we still want to have the dollars and the cents parts separate. We can use a struct or a class to do so.  For now you can think of them as more complicated variable types.  Below is the above code written using a struct.

// Program money_with_struct.C
// Rahman Tashakkori - CS1440-410
// A program that asks for your_money and my_money and then displays them
// and, also displays their sum.  In this program a money is made up two
// parts: the dollars part and the cents part both as integers.

#include <iostream>
using namespace std;

// Creating the new data type.  This variable type now contains two integers
struct Money

{
    int dollars;
    int cents;
};

void display_money(Money m);

// This is one way of doing this.
void add(Money m1, Money m2, Money& m);

int main( )
{
    //Pay attention here, we are declaring 3 variables of type Money
    Money my_money, your_money, sum_money;

    cout << "Enter the dollar part of your money ";
    cin >> your_money.dollars;
    cout << endl;
    cout << "Enter the cent part of your money ";
    cin >> your_money.cents;
    cout << endl;
    display_money(your_money);

    cout << "Enter the dollar part of my money ";
    cin >> my_money.dollars;
    cout << endl;
    cout << "Enter the cent part of my money ";
    cin >> my_money.cents;
    cout << endl;
    display_money(my_money);

    add(your_money, my_money, sum_money);
    cout << "The sum was: ";
    display_money(sum_money);

    return 0;
}

void display_money(Money m)
{
    cout << "$" << m.dollars << ".";
    if(m.cents < 10)
        cout << "0";
    cout << m.cents << endl;
    return;
}

void add(Money y, Money m, Money& s)
{
    s.dollars = y.dollars + m.dollars; //Sum the dollars up

    s.cents = y.cents + m.cents; //Sum the cents up

    s.dollars = s.dollars + s.cents/100;  //if cents > 100, add 1 to dollars for
                                                          // each 100 cents
    s.cents = s.cents%100; // count for those cents that are converted to dollars
}

Classes
So we used (struct) a new data type (struct) to bundle the dollars and the cents of each money together as one.  We were able to access each part using the "." operator.  Notice that we have accessed the dollars part of my_money in the main using my_money.dollars, and we also access it in the display and add functions in a similar way.  Similar thing is true for the cents part.

Now let's get a bit fancier.  We can write the program using a class instead of a struct.

A class with a set function
// Program money_with_class1.C
// Rahman Tashakkori - CS1440-410
// A program that asks for your_money and my_money and then displays them
// and, also displays their sum.  In this program a money is made up two
// parts: the dollars part and the cents part both as integers.

#include <iostream>
using namespace std;

//Pay attention here, we are creating a new type
class Money
{
  public:
    void set(int d, int c);
    void display_money();
    // This is one way of doing this.
    void add(Money m1, Money m2);
  private:
    int dollars;
    int cents;
};

int main( )
{
    Money my_money, your_money, sum_money;

    //Pay attention here
    int d, c;

    cout << "Enter the dollar part of your money ";
    cin >> d;
    cout << endl;
    cout << "Enter the cent part of your money ";
    cin >> c;
    cout << endl;

    //Pay attention here
    your_money.set(d, c);
    your_money.display_money();

    cout << "Enter the dollar part of my money ";
    cin >> d;
    cout << endl;
    cout << "Enter the cent part of my money ";
    cin >> c;
    cout << endl;

    my_money.set(d, c);
    my_money.display_money();

    sum_money.add(your_money, my_money);
    cout << "The sum was: ";
    sum_money.display_money();

    return 0;
}

//Pay attention here, a new functions that sets
//the dollars and cents to the values that are
//passed to it as arguments
void Money::set(int d, int c)
{
    dollars = d;
    cents = c;
}

//Pay attention here, adding scope resolution ::
void Money::display_money()
{

    //Pay attention here, no need for . operator here
    cout << "$" << dollars << ".";
    if(cents < 10)
        cout << "0";
    cout << cents << endl;
    return;
}

void Money::add(Money y, Money m)
{
    dollars = y.dollars + m.dollars; //Sum the dollars up

    cents = y.cents + m.cents; //Sum the cents up

    dollars = dollars + cents/100;  //if cents > 100, add 1 to dollars for
                                                  // each 100 cents
    cents = cents%100; // count for those cents that are converted to dollars
}

Let's have a quick look at the above program.  Here is the highlights:

Class with constructors

In the above program we created a class Money and then used it to declare objects of type Money in the main program.  Each object of type Money has two variable members, the dollars and the cents.   When we declare an object of type Money, these two do not have any value.  We can use the set function to set  values to them.  It is often desriable to set values at the time we declare the objects.  For that we can use a constructors.  A constructor will set the value of the variable members to default values that we have defined in the default constructor.  If we use a blank constructor for the default constructor, then the member variables will  be initialized the same way as before. Let's look at the above program with constructors.. 

// Program money_with_constructor.C
// Rahman Tashakkori - CS1440-410
// A program that asks for your_money and my_money and then displays them
// and, also display their sum.  In this program a money is made up two
// parts: the dollars part and the cents part both as integers.

#include <iostream>
using namespace std;

//Pay attention here
class Money
{
  public:
    //Pay attention here, we replaced the set function with constructors
    Money();  //default constructor
    Money(int d, int c);  // a constructor that set the values of dollars and cents to d and c respectively
    void display_money();
    // This is one way of doing this.
    void add(Money m1, Money m2);
  private:
    int dollars;
    int cents;
};

int main( )
{
    Money my_money, your_money, sum_money;

    //Pay attention here
    int d, c;

    cout << "Enter the dollar part of your money ";
    cin >> d;
    cout << endl;
    cout << "Enter the cent part of your money ";
    cin >> c;
    cout << endl;

    //Pay attention here, now with constructor we use =
    //instead of the .
    your_money = Money(d, c);
    your_money.display_money();

    cout << "Enter the dollar part of my money ";
    cin >> d;
    cout << endl;
    cout << "Enter the cent part of my money ";

    cin >> c;
    cout << endl;

    my_money = Money(d, c);
    my_money.display_money();

    sum_money.add(your_money, my_money);
    cout << "The sum was: ";
    sum_money.display_money();

    return 0;
}

Money::Money()
{

      // sets the values of dollars and cents to 0 when the object is declared
      dollars = 0;
      cents = 0;    

}

// Pay attention here, a new functions that sets
// the dollars and cents to the values that are passed to it as arguments
Money::Money(int d, int c)
{
    dollars = d;
    cents = c;
}

//Pay attention here, adding scope resolution ::
void Money::display_money()
{

    //Pay attention here, no need for . operator here
    cout << "$" << dollars << ".";
    if(cents < 10)
        cout << "0";
    cout << cents << endl;
    return;
}

void Money::add(Money y, Money m)
{
    dollars = y.dollars + m.dollars; //Sum the dollars up

    cents = y.cents + m.cents; //Sum the cents up

    dollars = dollars + cents/100;  //if cents > 100, add 1 to dollars for
                                                          // each 100 cents
    cents = cents%100; // count for those cents that are converted to dollars
}

Multiple Files
One last thing and we will be done.  In the above program, we used a class.  We can leave the class (heading) definition in one file, all the functions in one file, and the main in another one but make sure we see everything as before.  Here is what we will do.

// money.h file
#ifndef MONEY_H
 #define MONEY_H

class Money
{
  public:
    //Pay attention here, we replaced the set function with constructors
    Money();
    Money(int d, int c);
    void display_money();
    // This is one way of doing this.
    void add(Money m1, Money m2);
  private:
    int dollars;
    int cents;
};
#endif

// money.C file

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

Money::Money()
{
     //This one does not do anything for now
}

//Pay attention here, a new functions that sets
//the dollars and cents to the values that are
//passed to it as arguments
Money::Money(int d, int c)
{
    dollars = d;
    cents = c;
}

//Pay attention here, adding scope resolution ::
void Money::display_money()
{

    //Pay attention here, no need for . operator here
    cout << "$" << dollars << ".";
    if(cents < 10)
        cout << "0";
    cout << cents << endl;
    return;
}

void Money::add(Money y, Money m)
{
    dollars = y.dollars + m.dollars; //Sum the dollars up

    cents = y.cents + m.cents; //Sum the cents up

    dollars = dollars + cents/100;  //if cents > 100, add 1 to dollars for
                                                          // each 100 cents
    cents = cents%100; // count for those cents that are converted to dollars
}

// The main program - my_program.C
#include <iostream>
#include "money.h"

using namespace std;

int main( )
{
    Money my_money, your_money, sum_money;

    //Pay attention here
    int d, c;

    cout << "Enter the dollar part of your money ";
    cin >> d;
    cout << endl;
    cout << "Enter the cent part of your money ";
    cin >> c;
    cout << endl;

    //Pay attention here, now with constructor we use =
    //instead of the .
    your_money = Money(d, c);
    your_money.display_money();

    cout << "Enter the dollar part of my money ";
    cin >> d;
    cout << endl;
    cout << "Enter the cent part of my money ";

    cin >> c;
    cout << endl;

    my_money = Money(d, c);
    my_money.display_money();

    sum_money.add(your_money, my_money);
    cout << "The sum was: ";
    sum_money.display_money();

    return 0;
}

Now you can compile the program in a different way, but the program works the same.

% g++ my_program.C  money.C