home *** CD-ROM | disk | FTP | other *** search
/ C++ for Dummies (3rd Edition) / C_FD.iso / BUDGETS / BUDGET5_1.CPP < prev    next >
C/C++ Source or Header  |  1996-09-15  |  8KB  |  318 lines

  1. //BUDGET5.1c - this version splits the linked list into two
  2. //            by establishing two different pFirst pointers,
  3. //            one to the first Checking account object and
  4. //            the other to the first Savings account object.
  5. //
  6. //            This is the solution to problem 1c.
  7. //
  8.  
  9. #include <iostream.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12. //Account - this abstract class incorporates properties
  13. //          common to both account types Checking and
  14. //          Savings; however, itÆs missing the concept
  15. //          withdrawal( ) which is different between the two
  16. class Account
  17. {
  18.   protected:
  19.    Account(Account &c)
  20.    {
  21.       cout << "No creating funds\n";
  22.    }
  23.  
  24.    //this function adds an object to the list pointed
  25.    //at by the argument provided to the function
  26.    void addToList(Account * &pFirst);            //Note 1
  27.  
  28.   public:
  29.    Account(unsigned accNo, float initialBalance = 0.0F);
  30.  
  31.    //access functions
  32.    int accountNo( )
  33.    {
  34.       return accountNumber;
  35.    }
  36.    float acntBalance( )
  37.    {
  38.       return balance;
  39.    }
  40.  
  41.    static int noAccounts( )
  42.    {
  43.       return count;
  44.    }
  45.  
  46.    //transaction functions
  47.    void deposit(float amount)
  48.    {
  49.       balance += amount;
  50.    }
  51.    virtual void withdrawal(float amount) = 0;
  52.  
  53.    //display function for displaying self on æcoutÆ
  54.    void display( )
  55.    {
  56.       cout << "Account " << accountNumber
  57.            << " = "      << balance
  58.            << "\n";
  59.    }
  60.  
  61.    //make the following functions pure virtual
  62.    Account *next( )
  63.    {
  64.       return pNext;
  65.    }
  66.  
  67.  
  68.   protected:
  69.    static int count;         //number of accounts
  70.    unsigned   accountNumber;
  71.    float      balance;
  72.  
  73.    //pNext is still in Account but pFirst        //Note 2
  74.    //has now been relegated to the subclasses
  75.    Account   *pNext;
  76. };
  77. int Account::count = 0;
  78.  
  79. Account::Account(unsigned accNo, float initialBalance)
  80. {
  81.    accountNumber = accNo;
  82.    balance = initialBalance;
  83.    count++;
  84. }
  85.  
  86. //addToList - by accepting a reference to pFirst
  87. //            as an argument, addToList( ) can be called
  88. //            from either Checking or Savings
  89. void Account::addToList(Account * &pFirst)
  90. {
  91.    //this comes out of the constructor for Account
  92.    Account* pA;
  93.    if (pFirst == 0)
  94.    {
  95.       pFirst = this;      //empty list; make it first
  96.    }
  97.    else {                 //list not empty; look for last...
  98.                           //...entry in the list
  99.       for (pA = pFirst; pA->pNext; pA = pA->pNext)
  100.       {
  101.       }
  102.       pA->pNext = this;   //tack us onto end
  103.    }
  104.    pNext = 0;             //weÆre always last
  105. }
  106.  
  107. //Checking - this class contains properties unique to
  108. //           checking accounts.  Not much left is there?
  109. class Checking : public Account
  110. {
  111.   public:
  112.    //here the constructor defined inline
  113.    Checking(unsigned accNo, float initialBalance = 0.0F) :
  114.        Account(accNo, initialBalance)
  115.    {
  116.      addToList(Checking::pFirst);                //Note 3
  117.    }
  118.  
  119.    //overload pure virtual functions
  120.    virtual void withdrawal(float amount);
  121.  
  122.    //return first object in Checking account list
  123.    static Account* first( )                       //Note 4
  124.    {
  125.       return (Account*)Checking::pFirst;
  126.    }
  127.   protected:
  128.    static Account* pFirst;
  129. };
  130. Account *Checking::pFirst = 0;
  131.  
  132. void Checking::withdrawal(float amount)
  133. {
  134.    if (balance < amount)
  135.    {
  136.       cout << "Insufficient funds: balance " << balance
  137.            << ", check "                     << amount
  138.            << "\n";
  139.    }
  140.    else
  141.    {
  142.       balance -= amount;
  143.  
  144.       //if balance falls too low, charge service fee
  145.       if (balance < 500.00F)
  146.       {
  147.          balance -= 0.20F;
  148.       }
  149.    }
  150. }
  151.  
  152.  
  153. //Savings - same story as Checking except that it also
  154. //          has a unique data member
  155. class Savings : public Account
  156. {
  157.   public:
  158.    //here the constructor is defined as a separate
  159.    //function just to show you the difference
  160.    Savings(unsigned accNo, float initialBalance = 0.0F) :
  161.       Account(accNo, initialBalance)
  162.    {
  163.       noWithdrawals = 0;
  164.       addToList(Savings::pFirst);
  165.    }
  166.  
  167.    //transaction functions
  168.    virtual void withdrawal(float amount);
  169.    static Account* first( )
  170.    {
  171.       return (Account*)Savings::pFirst;
  172.    }
  173.  
  174.  
  175.   protected:
  176.    int        noWithdrawals;
  177.    static Account *pFirst;
  178. };
  179. Account* Savings::pFirst = 0;
  180.  
  181. void Savings::withdrawal(float amount)
  182. {
  183.    if (balance < amount)
  184.    {
  185.       cout << "Insufficient funds: balance " << balance
  186.            << ", withdrawal "                << amount
  187.            << "\n";
  188.    }
  189.    else
  190.    {
  191.       if (++noWithdrawals > 1)
  192.       {
  193.          balance -= 5.00F;
  194.       }
  195.       balance -= amount;
  196.    }
  197. }
  198.  
  199. //prototype declarations
  200. unsigned getAccntNo( );
  201. void process(Account &account);
  202. void outOfMemory( );
  203.  
  204.  
  205. //main - accumulate the initial input and output totals
  206. int main( )
  207. {
  208.    /*loop until someone enters an æXÆ or æxÆ*/
  209.    Account *pA;
  210.    char     accountType;     //S or C
  211.  
  212.    unsigned keepLooping = 1;
  213.    while (keepLooping)
  214.    {
  215.       cout << "Enter S for Savings, "
  216.               "C for Checking, X for exit\n";
  217.       cin  >> accountType;
  218.  
  219.       switch (accountType)
  220.       {
  221.          case 'c':
  222.          case 'C':
  223.             pA = new Checking(getAccntNo( ));
  224.             if (pA == 0)
  225.             {
  226.                outOfMemory( );
  227.             }
  228.             process(*pA);
  229.             break;
  230.  
  231.          case 's':
  232.          case 'S':
  233.             pA = new Savings(getAccntNo( ));
  234.             if (pA == 0)
  235.             {
  236.                outOfMemory( );
  237.             }
  238.             process(*pA);
  239.             break;
  240.          case 'x':
  241.          case 'X':
  242.             keepLooping = 0;
  243.             break;
  244.  
  245.          default:
  246.             cout << "I didn't get that.\n";
  247.       }
  248.    }
  249.  
  250.    //now present totals                          //Note 5
  251.    float subTotal = 0.0F;
  252.    float total = 0.0F;
  253.    cout << "Account totals:\n";
  254.  
  255.    //we are now forced to display the lists separately
  256.    for (pA = Checking::first( ); pA; pA = pA->next( ))
  257.    {
  258.       pA->display( );
  259.       subTotal += pA->acntBalance( );
  260.    }
  261.    cout << "Total of all checking accounts = " << subTotal << "\n";
  262.    total += subTotal;
  263.  
  264.    //repeat the process for savings
  265.    subTotal = 0.0F;
  266.    for (pA = Savings::first( ); pA; pA = pA->next( ))
  267.    {
  268.       pA->display( );
  269.       subTotal += pA->acntBalance( );
  270.    }
  271.    cout << "Total of all savings accounts = " << subTotal << "\n";
  272.    total += subTotal;
  273.  
  274.    cout << "Total worth of all accounts   = " << total << "\n";
  275.    return 0;
  276. }
  277.  
  278. //getAccntNo - return the account number entered
  279. unsigned getAccntNo( )
  280. {
  281.    unsigned accntNo;
  282.    cout << "Enter account number:";
  283.    cin  >> accntNo;
  284.    return accntNo;
  285. }
  286.  
  287. //process(Account) - input the data for an account*/
  288. void process(Account &account)
  289. {
  290.    cout << "Enter positive number for deposit,\n"
  291.            "negative for withdrawal, 0 to terminate";
  292.  
  293.    float transaction;
  294.    do
  295.    {
  296.       cout << ":";
  297.       cin  >> transaction;
  298.  
  299.       //deposit
  300.       if (transaction > 0.0F)
  301.       {
  302.          account.deposit(transaction);
  303.       }
  304.  
  305.       //withdrawal
  306.       if (transaction < 0.0F) {
  307.          account.withdrawal(-transaction);
  308.       }
  309.    } while (transaction != 0.0F);
  310. }
  311.  
  312. //outOfMemory - generate out-of-memory message and quit
  313. void outOfMemory( )
  314. {
  315.    cout << "Out of memory\n";
  316.    abort( );
  317. }
  318.