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

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