/*---------------------- atm_oop.cc: ATM machine ------------------- ATM machine (object-oriented implementation). Illustrates object-oriented approach, with classes representing accounts and transactions, derived classes representing subtypes of accounts & transactions, protected members and assertions to preserve meaning (semantics). This file implements the classes declared in atm_oop.h. File atm_oopt.cc provides a detailed trace of the program's activity. Programmer: Glenn D. Blank For chapter 14 of "The Universal Machine" Copyright (C) WCB/McGraw-Hill, 1998 ---------------------------------------------------------------------*/ #include "atm_oop.h" #include #include int Account :: getPIN() const //extract PIN { return PIN; } void Account :: setPIN(int pin) //insert PIN { assert(pin >= 1000 && pin <= 9999); //PIN must be 4 digits PIN = pin; } float Account :: getBalance() const //extract balance { return balance; } void Account :: setBalance(float bal) //insert balance { assert(bal >= 0); //no negative balance balance = bal; } float Account :: addToDeposits(float dep) //today's deposits { deposits = deposits + dep; return deposits; } float Account :: getDeposits() //extract deposits { return deposits; } float Account :: subFromBalance(float withdraw) { assert(balance > withdraw); balance = balance - withdraw; return balance; } bool Account :: sufficientBalance(float amount) //Enough in account to cover subtraction of amount? { return (balance >= amount); } const Lstring& Account :: getType() //extract accountType { return accountType; } void Account :: setType(Lstring type) //insert accountType { accountType = type; } //Constructor is protected; only call derived class constructors Account :: Account () //default constructor { deposits = 0; //today's balance start off zero } //For ATM, Checking and Savings add very little to Account // ... constructors just add Lstring accountType Checking :: Checking(int PIN,float balance) { setPIN(PIN); setBalance(balance); setType("checking"); } Checking :: Checking() {} //default Savings :: Savings(int PIN,float balance) { setPIN(PIN); setBalance(balance); Account::setType("savings"); } Savings :: Savings() {} //default //Transaction generalizes Deposits, Withdrawals, etc. float Transaction :: getAmount() const //extract amount { return amount; } void Transaction :: setAmount(float a) //insert amount { amount = a; } void Transaction :: askForAmount() //ask user for amount { cout << " amount (ddd.cc):$"; float userAmount; //from user cin >> userAmount; if (userAmount < 0) { cout << "Ignoring negative amount.\n"; setAmount(0); } else setAmount(userAmount); } //Deposit manages a deposit to any account Deposit :: Deposit(Account & account) //ask for amount and add to account's deposits { cout << "Deposit"; Transaction :: askForAmount(); //base class's function account.addToDeposits(amount); //add transaction amount cout << "New balance in " << account.getType() << " is $" << account.getBalance() + account.getDeposits() << endl; }; //Withdrawal manages a withdrawal from any account Withdrawal :: Withdrawal(Account & account) //ask for amount and subtract from account's balance { bool dispensed=false; //keep trying until money dispensed while (!dispensed) { cout << "Withdraw"; Transaction :: askForAmount(); //base class's function //can only dispense money in $20 bills if (amount != int(amount) || (int(amount) % 20)) cout << "Sorry, can only dispense money in $20 bills.\n"; else if (!account.sufficientBalance(amount)) //enough to cover? cout << "Sorry, insufficient balance in your " << account.getType() << " account.\n"; else //subtract from balance, dispense & show new balance { account.subFromBalance(amount); //subtract from balance cout << "Dispensing $" << amount << " from " << account.getType() << endl << "New balance in " << account.getType() << " is $" << account.getBalance() + account.getDeposits() << endl; dispensed = true; //exit while loop } //else } //while } //Card asks for user for card and verifies PIN void Card :: askForCard() //prompt user for card { cout << "Welcome to First Virtual Bank's Automatic Teller!\n" << "Please insert your ATM card.\n"; } bool Card :: validPin(int PIN,Account a) //verify user's PIN with account's PIN { return (PIN == a.getPIN()); } //ATM class runs the machine ATM :: ATM() //construct a user's accounts { checking = Checking(2468,1000.00); //start with $1000 balance savings = Savings(2468,200.00); //start with $200 balance } bool ATM :: verifyCard(Card card) { card.askForCard(); //verify PIN on card int i=0; //give user 3 changes to get PIN right int PIN=0; //from user while (!card.validPin(PIN,checking) && i < 3) { cout << "Please enter 4-digit PIN:"; cin >> PIN; i=i+1; } return card.validPin(PIN,checking); } char ATM :: chooseTransaction() //Deposit, Withdraw or Quit { char choice='?'; //from user while (choice != 'D' && choice != 'W' && choice != 'Q') { cout << "Select Deposit, Withdraw or Quit (d or w or q):"; cin >> choice; choice = toupper(choice); //user can enter lower or upper case } return choice; } char ATM :: chooseAccount() //Checking or Savings or Quit { char choice='?'; //from user while (choice != 'C' && choice != 'S' && choice != 'Q') { cout << "Select Checking, Savings or Quit (c or s or q):"; cin >> choice; choice = toupper(choice); //user can enter lower or upper case } return choice; } void ATM :: runTransaction(char transChoice, char accChoice) { if (transChoice == 'D' && accChoice == 'C') { Deposit d(checking); } //make Deposit to checking else if (transChoice == 'D' && accChoice == 'S') { Deposit d(savings); } //make Deposit to savings else if (transChoice == 'W' && accChoice == 'C') { Withdrawal w(checking); } //make Withdrawal from checking else if (transChoice == 'W' && accChoice == 'S') { Withdrawal w(savings); } //make Deposit to checking } void ATM :: goodbye() { //return card and say good-bye cout << "Please take your ATM card now." << endl; cout << "Thanks for using First Virtual Bank's ATM!" << endl; } void main() { ATM atm; //Start up ATM with checking & savings accounts Card card; if (atm.verifyCard(card)) //read and verify a card { char transChoice = atm.chooseTransaction(); while (transChoice != 'Q') { char accChoice = atm.chooseAccount(); if (accChoice != 'Q') atm.runTransaction(transChoice,accChoice); transChoice = atm.chooseTransaction(); } } atm.goodbye(); }