home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C++ for Dummies (3rd Edition)
/
C_FD.iso
/
WORKOUT
/
PART5.TXT
< prev
next >
Wrap
Text File
|
1996-09-06
|
16KB
|
512 lines
25-Minute Workout
Part V Answers
1
a. The solution I chose was to give Savings its old display() function back. To do this, I
made the following additions (things that remained the same are not shown):
class Account
{
//everything else the same as before
virtual void display( ); //make this a virtual function
};
//display - generic display function
// (virtual fns canÆt be inline)
void Account::display( )
{
cout << ôAccount ô << accountNumber
<< ô = ô << balance
<< ô\nö;
}
//Savings class with addition of display function
class Savings : public Account
{
public:
//everything else the same here, too
virtual void display( ); //add this declaration
};
//display - unique display function for Savings
void Savings::display( )
{
cout << ôAccount ô << accountNumber
<< ô = ô << balance
<< ô (no. withdrawals = ô << noWithdrawals
<< ô)\nö;
}
I declared Account::display() to be virtual so that I could overload it in the subclass
Savings. I then added the Savings::display() function from BUDGET4 to Savings.
Now, when main() displays the different accounts, the proper display() function is
chosen automatically, depending on the account type. The output of savings accounts
now appears with information on the number of withdrawals, as before:
Account totals:
Account 123 = 95 (no. withdrawals = 2)
Account 234 = 154.600006
Total worth = 249.600006
b. My class, NewSavings, appears as follows:
//NewSavings - implement a new savings account that charges
// no withdrawal fee if balance is >= 750
class NewSavings : public Savings
{
public:
NewSavings(unsigned accNo, float initialBalance = 0.0) :
Savings(accNo, initialBalance) {}
//transaction functions++
virtual void withdrawal(float amount);
};
void NewSavings::withdrawal(float amount)
{
if (balance < amount)
{
cout << ôInsufficient funds: balance ô << balance
<< ô, withdrawal ô << amount
<< ô\nö;
}
else
{
//if the balance is less than 750...
if (balance < 750.00F)
{
//...treat just like old savings account;
Savings::withdrawal(amount); //Note 1
}
//...otherwise,...
else
{
//...no service charge (Yeah!)
balance -= amount;
}
}
}
Here, you see that once again the member function withdrawal() is overloaded by
one, which has the desired effect. Notice, however, that if the balance is below $750,
this new withdrawal() calls the old Savings::withdrawal() (Note 1). Remember that
including the name of the class in the call forces it to bind early even if the function is
declared virtual.
c. Start with the separate list approach. This program does not differ much from the
BUDGET5 program presented earlier, but the changes are scattered over much of the
program. Therefore, to avoid confusion, IÆve repeated the entire program here:
//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
if (pFirst == 0)
{
pFirst = this; //empty list; make it first
}
else { //list not empty; look for last...
//...entry in the list
for (Account *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( );
int main( );
//main - accumulate the initial input and output totals
int main( )
{
/*l