G.8. Class BankDatabase

Class BankDatabase (Figs. G.13G.14) models the bank's database with which the ATM interacts to access and modify a user's account information. The class definition (Fig. G.13) declares function prototypes for the class's constructor and several member functions. We discuss these momentarily. The class definition also declares the BankDatabase's data members. We determine one data member for class BankDatabase based on its composition relationship with class Account. Recall from Fig. 13.28 that a BankDatabase is composed of zero or more objects of class Account. Line 24 of Fig. G.13 implements data member accountsa vector of Account objectsto implement this composition relationship. Lines 67 allow us to use vector in this file. Line 27 contains the function prototype for a private utility function getAccount that allows the member functions of the class to obtain a pointer to a specific Account in the accounts vector.


Figure G.13. BankDatabase class definition.

1 // BankDatabase.h 2 // BankDatabase class definition. Represents the bank's database. 3 #ifndef BANK_DATABASE_H 4 #define BANK_DATABASE_H 5 6 #include // class uses vector to store Account objects 7 using std::vector; 8 9 #include "Account.h" // Account class definition 10 11 class BankDatabase 12 { 13 public: 14 BankDatabase(); // constructor initializes accounts 15 16 // determine whether account number and PIN match those of an Account 17 bool authenticateUser( int, int ); // returns true if Account authentic 18 19 double getAvailableBalance( int ); // get an available balance 20 double getTotalBalance( int ); // get an Account's total balance 21 void credit( int, double ); // add amount to Account balance 22 void debit( int, double ); // subtract amount from Account balance 23 private: 24 vector< Account > accounts; // vector of the bank's Accounts 25 26 // private utility function 27 Account * getAccount( int ); // get pointer to Account object 28 }; // end class BankDatabase 29 30 #endif // BANK_DATABASE_H

Figure G.14. BankDatabase class member-function definitions.

(This item is displayed on pages 1301 - 1303 in the print version)

1 // BankDatabase.cpp 2 // Member-function definitions for class BankDatabase. 3 #include "BankDatabase.h" // BankDatabase class definition 4 5 // BankDatabase default constructor initializes accounts 6 BankDatabase::BankDatabase() 7 { 8 // create two Account objects for testing 9 Account account1( 12345, 54321, 1000.0, 1200.0 ); 10 Account account2( 98765, 56789, 200.0, 200.0 ); 11 12 // add the Account objects to the vector accounts 13 accounts.push_back( account1 ); // add account1 to end of vector 14 accounts.push_back( account2 ); // add account2 to end of vector 15 } // end BankDatabase default constructor 16 17 // retrieve Account object containing specified account number 18 Account * BankDatabase::getAccount( int accountNumber ) 19 { 20 // loop through accounts searching for matching account number 21 for ( size_t i = 0; i < accounts.size(); i++ ) 22 { 23 // return current account if match found 24 if ( accounts[ i ].getAccountNumber() == accountNumber ) 25 return &accounts[ i ]; 26 } // end for 27 28 return NULL; // if no matching account was found, return NULL 29 } // end function getAccount 30 31 // determine whether user-specified account number and PIN match 32 // those of an account in the database 33 bool BankDatabase::authenticateUser( int userAccountNumber, 34 int userPIN ) 35 { 36 // attempt to retrieve the account with the account number 37 Account * const userAccountPtr = getAccount( userAccountNumber ); 38 39 // if account exists, return result of Account function validatePIN 40 if ( userAccountPtr != NULL ) 41 return userAccountPtr->validatePIN( userPIN ); 42 else 43 return false; // account number not found, so return false 44 } // end function authenticateUser 45 46 // return available balance of Account with specified account number 47 double BankDatabase::getAvailableBalance( int userAccountNumber ) 48 { 49 Account * const userAccountPtr = getAccount( userAccountNumber ); 50 return userAccountPtr->getAvailableBalance(); 51 } // end function getAvailableBalance 52 53 // return total balance of Account with specified account number 54 double BankDatabase::getTotalBalance( int userAccountNumber ) 55 { 56 Account * const userAccountPtr = getAccount( userAccountNumber ); 57 return userAccountPtr->getTotalBalance(); 58 } // end function getTotalBalance 59 60 // credit an amount to Account with specified account number 61 void BankDatabase::credit( int userAccountNumber, double amount ) 62 { 63 Account * const userAccountPtr = getAccount( userAccountNumber ); 64 userAccountPtr->credit( amount ); 65 } // end function credit 66 67 // debit an amount from of Account with specified account number 68 void BankDatabase::debit( int userAccountNumber, double amount ) 69 { 70 Account * const userAccountPtr = getAccount( userAccountNumber ); 71 userAccountPtr->debit( amount ); 72 } // end function debit

BankDatabase Class Member-Function Definitions

Figure G.14 contains the member-function definitions for class BankDatabase. We implement the class with a default constructor (lines 615) that adds Account objects to data member accounts. For the sake of testing the system, we create two new Account objects with test data (lines 910), then add them to the end of the vector (lines 1314). Note that the Account constructor has four parametersthe account number, the PIN assigned to the account, the initial available balance and the initial total balance.


Recall that class BankDatabase serves as an intermediary between class ATM and the actual Account objects that contain users' account information. Thus, the member functions of class BankDatabase do nothing more than invoke the corresponding member functions of the Account object belonging to the current ATM user.

We include private utility function getAccount (lines 1829) to allow the BankDatabase to obtain a pointer to a particular Account within vector accounts. To locate the user's Account, the BankDatabase compares the value returned by member function getAccountNumber for each element of accounts to a specified account number until it finds a match. Lines 2126 traverse the accounts vector. If the account number of the current Account (i.e., accounts[ i ]) equals the value of parameter accountNumber, the member function immediately returns the address of the current Account (i.e., a pointer to the current Account). If no account has the given account number, then line 28 returns NULL. Note that this member function must return a pointer, as opposed to a reference, because there is the possibility that the return value could be NULLa reference cannot be NULL, but a pointer can.

Note that vector function size (invoked in the loop-continuation condition in line 21) returns the number of elements in a vector as a value of type size_t (which is usually unsigned int). As a result, we declare the control variable i to be of type size_t, too. On some compilers, declaring i as an int would cause the compiler to issue a warning message, because the loop-continuation condition would compare a signed value (i.e., an int) and an unsigned value (i.e., a value of type size_t).

Member function authenticateUser (lines 3344) proves or disproves the identity of an ATM user. This member function takes a user-specified account number and user-specified PIN as arguments and indicates whether they match the account number and PIN of an Account in the database. Line 37 calls utility function getAccount, which returns either a pointer to an Account with userAccountNumber as its account number or NULL to indicate that userAccountNumber is invalid. We declare userAccountPtr to be a const pointer because, once the member function aims this pointer at the user's Account, the pointer should not change. If getAccount returns a pointer to an Account object, line 41 returns the bool value returned by that object's validatePIN member function. Note that BankDatabase's authenticateUser member function does not perform the PIN comparison itselfrather, it forwards userPIN to the Account object's validatePIN member function to do so. The value returned by Account member function validatePIN indicates whether the user-specified PIN matches the PIN of the user's Account, so member function authenticateUser simply returns this value to the client of the class (i.e., ATM).


BankDatabase trusts the ATM to invoke member function authenticateUser and receive a return value of true before allowing the user to perform transactions. BankDatabase also trusts that each transaction object created by the ATM contains the valid account number of the current authenticated user and that this is the account number passed to the remaining BankDatabase member functions as argument userAccountNumber. Member functions getAvailableBalance (lines 4751), getTotalBalance (lines 5458), credit (lines 6165) and debit (lines 6872) therefore simply retrieve a pointer to the user's Account object with utility function getAccount, then use this pointer to invoke the appropriate Account member function on the user's Account object. We know that the calls to getAccount within these member functions will never return NULL, because userAccountNumber must refer to an existing Account. Note that getAvailableBalance and getTotalBalance return the values returned by the corresponding Account member functions. Also note that credit and debit simply redirect parameter amount to the Account member functions they invoke.

Категории