home *** CD-ROM | disk | FTP | other *** search
/ C++ for Dummies (3rd Edition) / C_FD.iso / WORKOUT / PART5.TXT < prev    next >
Text File  |  1996-09-06  |  16KB  |  512 lines

  1. 25-Minute Workout
  2. Part V Answers    
  3. 1
  4.     a.    The solution I chose was to give Savings its old display() function back. To do this, I 
  5. made the following additions (things that remained the same are not shown):
  6.     class Account
  7.     {
  8.        //everything else the same as before
  9.        virtual void display( );    //make this a virtual function
  10.     };
  11.  
  12.     //display - generic display function
  13.     //          (virtual fns canÆt be inline)
  14.     void Account::display( )
  15.     {
  16.           cout << ôAccount ô             << accountNumber
  17.                 << ô = ô                  << balance
  18.                << ô\nö;
  19.     }
  20.     
  21.     //Savings class with addition of display function
  22.     class Savings : public Account
  23.     {
  24.       public:
  25.        //everything else the same here, too
  26.        virtual void display( );    //add this declaration
  27.     };
  28.  
  29.     //display - unique display function for Savings
  30.     void Savings::display( )
  31.     {
  32.           cout  << ôAccount ô             << accountNumber
  33.                << ô = ô                  << balance
  34.                << ô (no. withdrawals = ô << noWithdrawals
  35.                << ô)\nö;
  36.     }
  37.         I declared Account::display() to be virtual so that I could overload it in the subclass 
  38. Savings. I then added the Savings::display() function from BUDGET4 to Savings. 
  39. Now, when main() displays the different accounts, the proper display() function is 
  40. chosen automatically, depending on the account type. The output of savings accounts 
  41. now appears with information on the number of withdrawals, as before:
  42.     Account totals:
  43.     Account 123 = 95 (no. withdrawals = 2)
  44.     Account 234 = 154.600006
  45.     Total worth  = 249.600006
  46.     b.    My class, NewSavings, appears as follows:
  47.     //NewSavings - implement a new savings account that charges
  48.     //             no withdrawal fee if balance is >= 750
  49.     class NewSavings : public Savings
  50.     {
  51.       public:
  52.        NewSavings(unsigned accNo, float initialBalance = 0.0) :
  53.              Savings(accNo, initialBalance) {}
  54.        //transaction functions++
  55.        virtual void withdrawal(float amount);
  56.     };
  57.  
  58.     void NewSavings::withdrawal(float amount)
  59.  
  60.     {
  61.        if (balance < amount)
  62.        {
  63.            cout << ôInsufficient funds: balance ô << balance
  64.                << ô, withdrawal ô                << amount
  65.                << ô\nö;
  66.        }
  67.         else
  68.         {
  69.            //if the balance is less than 750...
  70.            if (balance < 750.00F)
  71.             {
  72.                //...treat just like old savings account;
  73.             Savings::withdrawal(amount);   //Note 1
  74.            }
  75.           //...otherwise,...
  76.           else
  77.           {
  78.              //...no service charge (Yeah!)
  79.              balance -= amount;
  80.           }
  81.        }
  82.     }
  83.         Here, you see that once again the member function withdrawal() is overloaded by 
  84. one, which has the desired effect. Notice, however, that if the balance is below $750, 
  85. this new withdrawal() calls the old Savings::withdrawal() (Note 1). Remember that 
  86. including the name of the class in the call forces it to bind early even if the function is 
  87. declared virtual.
  88.     c.    Start with the separate list approach. This program does not differ much from the 
  89. BUDGET5 program presented earlier, but the changes are scattered over much of the 
  90. program. Therefore, to avoid confusion, IÆve repeated the entire program here:
  91. //BUDGET5.1c - this version splits the linked list into two
  92. //            by establishing two different pFirst pointers,
  93. //            one to the first Checking account object and
  94. //            the other to the first Savings account object.
  95. //
  96. //            This is the solution to problem 1c.
  97. //
  98.  
  99. #include <iostream.h>
  100. #include <stdlib.h>
  101. #include <ctype.h>
  102. //Account - this abstract class incorporates properties
  103. //          common to both account types Checking and
  104. //          Savings; however, itÆs missing the concept
  105. //          withdrawal( ) which is different between the two
  106. class Account
  107. {
  108.   protected:
  109.    Account(Account &c)
  110.    {
  111.       cout << ôNo creating funds\nö;
  112.    }
  113.  
  114.    //this function adds an object to the list pointed
  115.    //at by the argument provided to the function
  116.    void addToList(Account * &pFirst);            //Note 1
  117.  
  118.   public:
  119.    Account(unsigned accNo, float initialBalance = 0.0F);
  120.  
  121.    //access functions
  122.    int accountNo( )
  123.    {
  124.       return accountNumber;
  125.    }
  126.    float acntBalance( )
  127.    {
  128.       return balance;
  129.    }
  130.  
  131.    static int noAccounts( )
  132.    {
  133.       return count;
  134.    }
  135.  
  136.    //transaction functions
  137.    void deposit(float amount)
  138.    {
  139.       balance += amount;
  140.    }
  141.    virtual void withdrawal(float amount) = 0;
  142.  
  143.    //display function for displaying self on æcoutÆ
  144.    void display( )
  145.    {
  146.       cout << ôAccount ô << accountNumber
  147.            << ô = ô      << balance
  148.            << ô\nö;
  149.    }
  150.  
  151.    //make the following functions pure virtual
  152.    Account *next( )
  153.    {
  154.       return pNext;
  155.    }
  156.  
  157.  
  158.   protected:
  159.    static int count;         //number of accounts
  160.    unsigned   accountNumber;
  161.    float      balance;
  162.  
  163.    //pNext is still in Account but pFirst        //Note 2
  164.    //has now been relegated to the subclasses
  165.    Account   *pNext;
  166. };
  167. int Account::count = 0;
  168.  
  169. Account::Account(unsigned accNo, float initialBalance)
  170. {
  171.    accountNumber = accNo;
  172.    balance = initialBalance;
  173.    count++;
  174. }
  175.  
  176. //addToList - by accepting a reference to pFirst
  177. //            as an argument, addToList( ) can be called
  178. //            from either Checking or Savings
  179. void Account::addToList(Account * &pFirst)
  180. {
  181.    //this comes out of the constructor for Account
  182.    if (pFirst == 0)
  183.    {
  184.       pFirst = this;      //empty list; make it first
  185.    }
  186.    else {                 //list not empty; look for last...
  187.                           //...entry in the list
  188.       for (Account *pA = pFirst; pA->pNext; pA = pA->pNext)
  189.       {
  190.       }
  191.       pA->pNext = this;   //tack us onto end
  192.    }
  193.    pNext = 0;             //weÆre always last
  194. }
  195.  
  196. //Checking - this class contains properties unique to
  197. //           checking accounts.  Not much left is there?
  198. class Checking : public Account
  199. {
  200.   public:
  201.    //here the constructor defined inline
  202.    Checking(unsigned accNo, float initialBalance = 0.0F) :
  203.        Account(accNo, initialBalance)
  204.    {
  205.      addToList(Checking::pFirst);                //Note 3
  206.    }
  207.  
  208.    //overload pure virtual functions
  209.    virtual void withdrawal(float amount);
  210.  
  211.    //return first object in Checking account list
  212.    static Account* first( )                       //Note 4
  213.    {
  214.       return (Account*)Checking::pFirst;
  215.    }
  216.   protected:
  217.    static Account* pFirst;
  218. };
  219. Account *Checking::pFirst = 0;
  220.  
  221. void Checking::withdrawal(float amount)
  222. {
  223.    if (balance < amount)
  224.    {
  225.       cout << ôInsufficient funds: balance ô << balance
  226.            << ô, check ô                     << amount
  227.            << ô\nö;
  228.    }
  229.    else
  230.    {
  231.       balance -= amount;
  232.  
  233.       //if balance falls too low, charge service fee
  234.       if (balance < 500.00F)
  235.       {
  236.          balance -= 0.20F;
  237.       }
  238.    }
  239. }
  240.  
  241.  
  242. //Savings - same story as Checking except that it also
  243. //          has a unique data member
  244. class Savings : public Account
  245. {
  246.   public:
  247.    //here the constructor is defined as a separate
  248.    //function just to show you the difference
  249.    Savings(unsigned accNo, float initialBalance = 0.0F) :
  250.       Account(accNo, initialBalance)
  251.    {
  252.       noWithdrawals = 0;
  253.       addToList(Savings::pFirst);
  254.    }
  255.  
  256.    //transaction functions
  257.    virtual void withdrawal(float amount);
  258.    static Account* first( )
  259.    {
  260.       return (Account*)Savings::pFirst;
  261.    }
  262.  
  263.  
  264.   protected:
  265.    int        noWithdrawals;
  266.    static Account *pFirst;
  267. };
  268. Account* Savings::pFirst = 0;
  269.  
  270. void Savings::withdrawal(float amount)
  271. {
  272.    if (balance < amount)
  273.    {
  274.       cout << ôInsufficient funds: balance ô << balance
  275.            << ô, withdrawal ô                << amount
  276.            << ô\nö;
  277.    }
  278.    else
  279.    {
  280.       if (++noWithdrawals > 1)
  281.       {
  282.          balance -= 5.00F;
  283.       }
  284.       balance -= amount;
  285.    }
  286. }
  287.  
  288. //prototype declarations
  289. unsigned getAccntNo( );
  290. void process(Account &account);
  291. void outOfMemory( );
  292. int main( );
  293.  
  294. //main - accumulate the initial input and output totals
  295. int main( )
  296. {
  297.    /*l