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