home *** CD-ROM | disk | FTP | other *** search
- //BUDGET5.1c - this version splits the linked list into two
- // by establishing two different pFirst pointers,
- // one to the first Checking account object and
- // the other to the first Savings account object.
- //
- // This is the solution to problem 1c.
- //
-
- #include <iostream.h>
- #include <stdlib.h>
- #include <ctype.h>
- //Account - this abstract class incorporates properties
- // common to both account types Checking and
- // Savings; however, itÆs missing the concept
- // withdrawal( ) which is different between the two
- class Account
- {
- protected:
- Account(Account &c)
- {
- cout << "No creating funds\n";
- }
-
- //this function adds an object to the list pointed
- //at by the argument provided to the function
- void addToList(Account * &pFirst); //Note 1
-
- public:
- Account(unsigned accNo, float initialBalance = 0.0F);
-
- //access functions
- int accountNo( )
- {
- return accountNumber;
- }
- float acntBalance( )
- {
- return balance;
- }
-
- static int noAccounts( )
- {
- return count;
- }
-
- //transaction functions
- void deposit(float amount)
- {
- balance += amount;
- }
- virtual void withdrawal(float amount) = 0;
-
- //display function for displaying self on æcoutÆ
- void display( )
- {
- cout << "Account " << accountNumber
- << " = " << balance
- << "\n";
- }
-
- //make the following functions pure virtual
- Account *next( )
- {
- return pNext;
- }
-
-
- protected:
- static int count; //number of accounts
- unsigned accountNumber;
- float balance;
-
- //pNext is still in Account but pFirst //Note 2
- //has now been relegated to the subclasses
- Account *pNext;
- };
- int Account::count = 0;
-
- Account::Account(unsigned accNo, float initialBalance)
- {
- accountNumber = accNo;
- balance = initialBalance;
- count++;
- }
-
- //addToList - by accepting a reference to pFirst
- // as an argument, addToList( ) can be called
- // from either Checking or Savings
- void Account::addToList(Account * &pFirst)
- {
- //this comes out of the constructor for Account
- Account* pA;
- if (pFirst == 0)
- {
- pFirst = this; //empty list; make it first
- }
- else { //list not empty; look for last...
- //...entry in the list
- for (pA = pFirst; pA->pNext; pA = pA->pNext)
- {
- }
- pA->pNext = this; //tack us onto end
- }
- pNext = 0; //weÆre always last
- }
-
- //Checking - this class contains properties unique to
- // checking accounts. Not much left is there?
- class Checking : public Account
- {
- public:
- //here the constructor defined inline
- Checking(unsigned accNo, float initialBalance = 0.0F) :
- Account(accNo, initialBalance)
- {
- addToList(Checking::pFirst); //Note 3
- }
-
- //overload pure virtual functions
- virtual void withdrawal(float amount);
-
- //return first object in Checking account list
- static Account* first( ) //Note 4
- {
- return (Account*)Checking::pFirst;
- }
- protected:
- static Account* pFirst;
- };
- Account *Checking::pFirst = 0;
-
- void Checking::withdrawal(float amount)
- {
- if (balance < amount)
- {
- cout << "Insufficient funds: balance " << balance
- << ", check " << amount
- << "\n";
- }
- else
- {
- balance -= amount;
-
- //if balance falls too low, charge service fee
- if (balance < 500.00F)
- {
- balance -= 0.20F;
- }
- }
- }
-
-
- //Savings - same story as Checking except that it also
- // has a unique data member
- class Savings : public Account
- {
- public:
- //here the constructor is defined as a separate
- //function just to show you the difference
- Savings(unsigned accNo, float initialBalance = 0.0F) :
- Account(accNo, initialBalance)
- {
- noWithdrawals = 0;
- addToList(Savings::pFirst);
- }
-
- //transaction functions
- virtual void withdrawal(float amount);
- static Account* first( )
- {
- return (Account*)Savings::pFirst;
- }
-
-
- protected:
- int noWithdrawals;
- static Account *pFirst;
- };
- Account* Savings::pFirst = 0;
-
- void Savings::withdrawal(float amount)
- {
- if (balance < amount)
- {
- cout << "Insufficient funds: balance " << balance
- << ", withdrawal " << amount
- << "\n";
- }
- else
- {
- if (++noWithdrawals > 1)
- {
- balance -= 5.00F;
- }
- balance -= amount;
- }
- }
-
- //prototype declarations
- unsigned getAccntNo( );
- void process(Account &account);
- void outOfMemory( );
-
-
- //main - accumulate the initial input and output totals
- int main( )
- {
- /*loop until someone enters an æXÆ or æxÆ*/
- Account *pA;
- char accountType; //S or C
-
- unsigned keepLooping = 1;
- while (keepLooping)
- {
- cout << "Enter S for Savings, "
- "C for Checking, X for exit\n";
- cin >> accountType;
-
- switch (accountType)
- {
- case 'c':
- case 'C':
- pA = new Checking(getAccntNo( ));
- if (pA == 0)
- {
- outOfMemory( );
- }
- process(*pA);
- break;
-
- case 's':
- case 'S':
- pA = new Savings(getAccntNo( ));
- if (pA == 0)
- {
- outOfMemory( );
- }
- process(*pA);
- break;
- case 'x':
- case 'X':
- keepLooping = 0;
- break;
-
- default:
- cout << "I didn't get that.\n";
- }
- }
-
- //now present totals //Note 5
- float subTotal = 0.0F;
- float total = 0.0F;
- cout << "Account totals:\n";
-
- //we are now forced to display the lists separately
- for (pA = Checking::first( ); pA; pA = pA->next( ))
- {
- pA->display( );
- subTotal += pA->acntBalance( );
- }
- cout << "Total of all checking accounts = " << subTotal << "\n";
- total += subTotal;
-
- //repeat the process for savings
- subTotal = 0.0F;
- for (pA = Savings::first( ); pA; pA = pA->next( ))
- {
- pA->display( );
- subTotal += pA->acntBalance( );
- }
- cout << "Total of all savings accounts = " << subTotal << "\n";
- total += subTotal;
-
- cout << "Total worth of all accounts = " << total << "\n";
- return 0;
- }
-
- //getAccntNo - return the account number entered
- unsigned getAccntNo( )
- {
- unsigned accntNo;
- cout << "Enter account number:";
- cin >> accntNo;
- return accntNo;
- }
-
- //process(Account) - input the data for an account*/
- void process(Account &account)
- {
- cout << "Enter positive number for deposit,\n"
- "negative for withdrawal, 0 to terminate";
-
- float transaction;
- do
- {
- cout << ":";
- cin >> transaction;
-
- //deposit
- if (transaction > 0.0F)
- {
- account.deposit(transaction);
- }
-
- //withdrawal
- if (transaction < 0.0F) {
- account.withdrawal(-transaction);
- }
- } while (transaction != 0.0F);
- }
-
- //outOfMemory - generate out-of-memory message and quit
- void outOfMemory( )
- {
- cout << "Out of memory\n";
- abort( );
- }
-