G.11. Class Withdrawal

Class Withdrawal (Figs. G.19G.20) derives from TRansaction and represents a withdrawal ATM transaction. Figure G.19 expands upon the header file for this class developed in Fig. 13.31. Class Withdrawal has a constructor and one member function execute, which we discuss shortly. Recall from the class diagram of Fig. 13.29 that class Withdrawal has one attribute, amount, which line 16 implements as an int data member. Figure 13.28 models associations between class Withdrawal and classes Keypad and CashDispenser, for which lines 1718 implement references keypad and cashDispenser, respectively. Line 19 is the function prototype of a private utility function that we soon discuss.


Figure G.19. Withdrawal class definition.

(This item is displayed on page 1308 in the print version)

 1 // Withdrawal.h
 2 // Withdrawal class definition. Represents a withdrawal transaction.
 3 #ifndef WITHDRAWAL_H
 4 #define WITHDRAWAL_H
 5
 6 #include "Transaction.h" // Transaction class definition
 7 class Keypad; // forward declaration of class Keypad
 8 class CashDispenser; // forward declaration of class CashDispenser
 9
10 class Withdrawal : public Transaction
11 {
12 public:
13 Withdrawal( int, Screen &, BankDatabase &, Keypad &, CashDispenser & );
14 virtual void execute(); // perform the transaction
15 private:
16 int amount; // amount to withdraw
17 Keypad &keypad; // reference to ATM's keypad
18 CashDispenser &cashDispenser; // reference to ATM's cash dispenser
19 int displayMenuOfAmounts() const; // display the withdrawal menu
20 }; // end class Withdrawal
21
22 #endif // WITHDRAWAL_H

Figure G.20. Withdrawal class member-function definitions.

(This item is displayed on pages 1309 - 1311 in the print version)

 1 // Withdrawal.cpp
 2 // Member-function definitions for class Withdrawal.
 3 #include "Withdrawal.h" // Withdrawal class definition
 4 #include "Screen.h" // Screen class definition
 5 #include "BankDatabase.h" // BankDatabase class definition
 6 #include "Keypad.h" // Keypad class definition
 7 #include "CashDispenser.h" // CashDispenser class definition
 8
 9 // global constant that corresponds to menu option to cancel
10 const static int CANCELED = 6;
11
12 // Withdrawal constructor initialize class's data members
13 Withdrawal::Withdrawal( int userAccountNumber, Screen &atmScreen,
14 BankDatabase &atmBankDatabase, Keypad &atmKeypad,
15 CashDispenser &atmCashDispenser )
16 : Transaction( userAccountNumber, atmScreen, atmBankDatabase ),
17 keypad( atmKeypad ), cashDispenser( atmCashDispenser )
18 {
19 // empty body
20 } // end Withdrawal constructor
21
22 // perform transaction; overrides Transaction's pure virtual function
23 void Withdrawal::execute()
24 {
25 bool cashDispensed = false; // cash was not dispensed yet
26 bool transactionCanceled = false; // transaction was not canceled yet
27
28 // get references to bank database and screen
29 BankDatabase &bankDatabase = getBankDatabase();
30 Screen &screen = getScreen();
31
32 // loop until cash is dispensed or the user cancels
33 do
34 {
35 // obtain the chosen withdrawal amount from the user
36 int selection = displayMenuOfAmounts();
37
38 // check whether user chose a withdrawal amount or canceled
39 if ( selection != CANCELED )
40 {
41 amount = selection; // set amount to the selected dollar amount
42
43 // get available balance of account involved
44 double availableBalance =
45 bankDatabase.getAvailableBalance( getAccountNumber() );
46
47 // check whether the user has enough money in the account
48 if ( amount <= availableBalance )
49 {
50 // check whether the cash dispenser has enough money
51 if ( cashDispenser.isSufficientCashAvailable( amount ) )
52 {
53 // update the account involved to reflect withdrawal
54 bankDatabase.debit( getAccountNumber(), amount );
55
56 cashDispenser.dispenseCash( amount ); // dispense cash
57 cashDispensed = true; // cash was dispensed
58
59 // instruct user to take cash
60 screen.displayMessageLine(
61 "
Please take your cash from the cash dispenser." );
62 } // end if
63 else // cash dispenser does not have enough cash
64 screen.displayMessageLine(
65 "
Insufficient cash available in the ATM."
66 "

Please choose a smaller amount." );
67 } // end if
68 else // not enough money available in user's account
69 {
70 screen.displayMessageLine(
71 "
Insufficient funds in your account."
72 "

Please choose a smaller amount." );
73 } // end else
74 } // end if
75 else // user chose cancel menu option
76 {
77 screen.displayMessageLine( "
Canceling transaction..." );
78 transactionCanceled = true; // user canceled the transaction
79 } // end else
80 } while ( !cashDispensed && !transactionCanceled ); // end do...while
81 } // end function execute
82
83 // display a menu of withdrawal amounts and the option to cancel;
84 // return the chosen amount or 0 if the user chooses to cancel
85 int Withdrawal::displayMenuOfAmounts() const
86 {
87 int userChoice = 0; // local variable to store return value
88
89 Screen &screen = getScreen(); // get screen reference
90
91 // array of amounts to correspond to menu numbers
92 int amounts[] = { 0, 20, 40, 60, 100, 200 };
93
94 // loop while no valid choice has been made
95 while ( userChoice == 0 )
96 {
97 // display the menu
98 screen.displayMessageLine( "
Withdrawal options:" );
99 screen.displayMessageLine( "1 - $20" );
100 screen.displayMessageLine( "2 - $40" );
101 screen.displayMessageLine( "3 - $60" );
102 screen.displayMessageLine( "4 - $100" );
103 screen.displayMessageLine( "5 - $200" );
104 screen.displayMessageLine( "6 - Cancel transaction" );
105 screen.displayMessage( "
Choose a withdrawal option (1-6): " );
106
107 int input = keypad.getInput(); // get user input through keypad
108
109 // determine how to proceed based on the input value
110 switch ( input )
111 {
112 case 1: // if the user chose a withdrawal amount
113 case 2: // (i.e., chose option 1, 2, 3, 4 or 5), return the
114 case 3: // corresponding amount from amounts array
115 case 4:
116 case 5:
117 userChoice = amounts[ input ]; // save user's choice
118 break;
119 case CANCELED: // the user chose to cancel
120 userChoice = CANCELED; // save user's choice
121 break;
122 default: // the user did not enter a value from 1-6
123 screen.displayMessageLine(
124 "
Ivalid selection. Try again." );
125 } // end switch
126 } // end while
127
128 return userChoice; // return withdrawal amount or CANCELED
129 } // end function displayMenuOfAmounts

Withdrawal Class Member-Function Definitions

Figure G.20 contains the member-function definitions for class Withdrawal. Line 3 #includes the class's definition, and lines 47 #include the definitions of the other classes used in Withdrawal's member functions. Line 11 declares a global constant corresponding to the cancel option on the withdrawal menu. We will soon discuss how the class uses this constant.

Class Withdrawal's constructor (defined in lines 1320 of Fig. G.20) has five parameters. It uses a base-class initializer in line 16 to pass parameters userAccountNumber, atm-Screen and atmBankDatabase to base class transaction's constructor to set the data members that Withdrawal inherits from TRansaction. The constructor also takes references atmKeypad and atmCashDispenser as parameters and assigns them to reference data members keypad and cashDispenser using member initializers (line 17).

Class Withdrawal overrides transaction's pure virtual function execute with a concrete implementation (lines 2381) that performs the steps involved in a withdrawal. Line 25 declares and initializes a local bool variable cashDispensed. This variable indicates whether cash has been dispensed (i.e., whether the transaction has completed successfully) and is initially false. Line 26 declares and initializes to false a bool variable transactionCanceled that indicates whether the transaction has been canceled by the user. Lines 2930 get references to the bank database and the ATM's screen by invoking member functions inherited from base class transaction.


Lines 3380 contain a do...while statement that executes its body until cash is dispensed (i.e., until cashDispensed becomes true) or until the user chooses to cancel (i.e., until transactionCanceled becomes true). We use this loop to continuously return the user to the start of the transaction if an error occurs (i.e., the requested withdrawal amount is greater than the user's available balance or greater than the amount of cash in the cash dispenser). Line 36 displays a menu of withdrawal amounts and obtains a user selection by calling private utility function displayMenuOfAmounts (defined in lines 85129). This member function displays the menu of amounts and returns either an int withdrawal amount or the int constant CANCELED to indicate that the user has chosen to cancel the transaction.

Member function displayMenuOfAmounts (lines 85129) first declares local variable userChoice (initially 0) to store the value that the member function will return (line 87). Line 89 gets a reference to the screen by calling member function getScreen inherited from base class transaction. Line 92 declares an integer array of withdrawal amounts that correspond to the amounts displayed in the withdrawal menu. We ignore the first element in the array (index 0) because the menu has no option 0. The while statement at lines 95126 repeats until userChoice takes on a value other than 0. We will see shortly that this occurs when the user makes a valid selection from the menu. Lines 98105 display the withdrawal menu on the screen and prompt the user to enter a choice. Line 107 obtains integer input through the keypad. The switch statement at lines 110125 determines how to proceed based on the user's input. If the user selects a number between 1 and 5, line 117 sets userChoice to the value of the element in amounts at index input. For example, if the user enters 3 to withdraw $60, line 117 sets userChoice to the value of amounts[ 3 ] (i.e., 60). Line 118 terminates the switch. Variable userChoice no longer equals 0, so the while at lines 95126 terminates and line 128 returns userChoice. If the user selects the cancel menu option, lines 120121 execute, setting userChoice to CANCELED and causing the member function to return this value. If the user does not enter a valid menu selection, lines 123124 display an error message and the user is returned to the withdrawal menu.

The if statement at line 39 in member function execute determines whether the user has selected a withdrawal amount or chosen to cancel. If the user cancels, lines 7778 execute to display an appropriate message to the user and set transactionCanceled to true. This causes the loop-continuation test in line 80 to fail and control to return to the calling member function (i.e., ATM member function performTransactions). If the user has chosen a withdrawal amount, line 41 assigns local variable selection to data member amount. Lines 4445 retrieve the available balance of the current user's Account and store it in a local double variable availableBalance. Next, the if statement at line 48 determines whether the selected amount is less than or equal to the user's available balance. If it is not, lines 7072 display an appropriate error message. Control then continues to the end of the do...while, and the loop repeats because both cashDispensed and transactionCanceled are still false. If the user's balance is high enough, the if statement at line 51 determines whether the cash dispenser has enough money to satisfy the withdrawal request by invoking the cashDispenser's isSufficientCashAvailable member function. If this member function returns false, lines 6466 display an appropriate error message and the do...while repeats. If sufficient cash is available, then the requirements for the withdrawal are satisfied, and line 54 debits amount from the user's account in the database. Lines 5657 then instruct the cash dispenser to dispense the cash to the user and set cashDispensed to TRue. Finally, lines 6061 display a message to the user that cash has been dispensed. Because cashDispensed is now TRue, control continues after the do...while. No additional statements appear below the loop, so the member function returns control to class ATM.


Notice that, in the function calls in lines 6466 and lines 7072, we divide the argument to Screen member function displayMessageLine into two string literals, each placed on a separate line in the program. We do so because each argument is too long to fit on a single line. C++ concatenates (i.e., combines) string literals adjacent to each other, even if they are on separate lines. For example, if you write "Happy ""Birthday" in a program, C++ will view these two adjacent string literals as the single string literal "Happy Birthday". As a result, when lines 6466 execute, displayMessageLine receives a single string as a parameter, even though the argument in the function call appears as two string literals.





C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627
Simiral book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net