Witam, mam problem z moim programem. Można go włączyć,ale po dwukrotnym wyświetleniu pierwszej opcji(inne opcje jeszcze nie działają) zostaje wyrzucony wyjątek o naruszeniu dostępu do odczytu. W programie chciałbym użyć polimorfizmu, stąd też takie rozwiązanie. Jakby ktoś był w stanie mi wytłumaczyć co robię źle to byłbym wdzięczny. Z góry dziękuję.
#include<iostream>
#include<string>
#include<conio.h>
using namespace std;
class Screen
{
public:
void displayMessage(string message)
{
cout << message;
}
void displayMessageLine(string message)
{
cout << message << endl;
}
void displayDollarAmount(double amount)
{
cout << "$" << amount;
}
};
class Keypad
{
int nr;
public:
Keypad()
{
nr = 0;
}
int getInput()
{
cin >> nr;
return nr;
}
};
class Account
{
int accountNumber;
int pin;
double availableBalance;
double totalBalance;
public:
Account(){}
Account(int theAccountNumber, int thePIN, double theAvailableBalance, double theTotalBalane)
{
accountNumber = theAccountNumber;
pin = thePIN;
availableBalance = theAvailableBalance;
totalBalance = theTotalBalane;
}
bool validatePIN(int userPIN)
{
if (userPIN == pin)
return true;
else
return false;
}
double getAvailableBalance()
{
return availableBalance;
}
double getTotalBalance()
{
return totalBalance;
}
void credit(double amount)
{
totalBalance += amount;
}
void debit(double amount)
{
availableBalance -= amount;
totalBalance -= amount;
}
int getAccountNumber()
{
return accountNumber;
}
};
class BankDatabase
{
Account*accounts;
public:
BankDatabase()
{
accounts = new Account[2];
accounts[0] = Account(12345, 54321, 1000.0, 1200.0);
accounts[1] = Account(98765, 56789, 200.0, 200.0);
}
~BankDatabase()
{
delete[] accounts;
}
private:
Account*getAccount(int accountNumber)
{
Account*currentAccount = accounts;
for(int i=0;i<2;i++)
{
if (currentAccount->getAccountNumber() == accountNumber)
{
return currentAccount;
}
currentAccount++;
}
return nullptr;
}
public:
bool authenticateUser(int userAccountNumber, int userPIN)
{
Account*userAccount = getAccount(userAccountNumber);
if (userAccount != nullptr)
{
return userAccount->validatePIN(userPIN);
}
else
return false;
}
double getAvailableBalance(int userAccountNumber)
{
return getAccount(userAccountNumber)->getAvailableBalance();
}
double getTotalBalance(int userAccountNumber)
{
return getAccount(userAccountNumber)->getTotalBalance();
}
void credit(int userAccountNumber, double amount)
{
getAccount(userAccountNumber)->credit(amount);
}
void debit(int userAccountNumber, double amount)
{
getAccount(userAccountNumber)->debit(amount);
}
};
class Transaction
{
protected:
int accountNumber;
Screen*screen;
BankDatabase*bankDatabase;
public:
Transaction(int userAccountNumber, Screen &atmScreen,BankDatabase &atmBankDatabase)
{
screen = new Screen;
bankDatabase = new BankDatabase;
accountNumber = userAccountNumber;
screen = &atmScreen;
bankDatabase = &atmBankDatabase;
}
~Transaction()
{
delete screen;
delete bankDatabase;
}
int getAccountNumber()
{
return accountNumber;
}
Screen*getScreen()
{
return screen;
}
BankDatabase*getBankDatabase()
{
return bankDatabase;
}
virtual void execute() = 0;
};
class BalanceInquiry : public Transaction
{
public:
BalanceInquiry(int userAccountNumer, Screen atmScreen, BankDatabase atmBankDatabase):Transaction(userAccountNumer, atmScreen, atmBankDatabase)
{
screen = new Screen;
bankDatabase = new BankDatabase;
}
~BalanceInquiry()
{
delete screen;
delete bankDatabase;
}
void execute()
{
BankDatabase*bankDatabase =getBankDatabase();
Screen*screen = screen=getScreen();
double availableBalance = bankDatabase->getAvailableBalance(getAccountNumber());
double totalBalance = bankDatabase->getTotalBalance(getAccountNumber());
screen->displayMessageLine("\nBalance Information:");
screen->displayMessage(" - Available balance:");
screen->displayDollarAmount(availableBalance);
screen->displayMessage("\n - Total balance: ");
screen->displayDollarAmount(totalBalance);
screen->displayMessageLine("");
}
};
class ATM
{
bool userAuthenticated;
int currentAccountNumber;
Screen*screen;
Keypad*keypad;
BankDatabase*bankDatabase;
Transaction*tmp;
enum { BALANCE_INQUIRY=1, WITHDRAWAL=2, DEPOSIT=3, EXIT=4 };
public:
ATM()
{
userAuthenticated = false;
currentAccountNumber = 0;
screen = new Screen;
keypad = new Keypad;
bankDatabase = new BankDatabase;
tmp = nullptr;
}
~ATM()
{
delete screen;
delete keypad;
delete bankDatabase;
delete tmp;
}
void run()
{
while (true)
{
while (!userAuthenticated)
{
screen->displayMessageLine("\nWelcome!");
authenticateUser();
}
performTransactions();
userAuthenticated = false;
currentAccountNumber = 0;
screen->displayMessageLine("\nThank you! Goodbye");
}
}
private:
void authenticateUser()
{
screen->displayMessage("\nPlease enter your account number: ");
int accountNumber = keypad->getInput();
screen->displayMessage("\nEnter your PIN: ");
int pin = keypad->getInput();
userAuthenticated =bankDatabase->authenticateUser(accountNumber, pin);
if (userAuthenticated)
{
currentAccountNumber = accountNumber;
}
else
screen->displayMessageLine("Invalid account number or PIN. Please try again.");
}
void performTransactions()
{
bool userExited = false;
while (!userExited)
{
Transaction*currentTransaction= nullptr;
int mainMenuSelection = displayMainMenu();
switch (mainMenuSelection)
{
case BALANCE_INQUIRY:
case WITHDRAWAL:
case DEPOSIT:
currentTransaction = createTransaction(mainMenuSelection);
currentTransaction->execute();
break;
case EXIT:
screen->displayMessageLine("\nExiting the system...");
userExited = true;
break;
default:
screen->displayMessageLine("\nYou did not enter a valid selection. Try again.");
break;
}
}
}
int displayMainMenu()
{
screen->displayMessageLine("\nMain menu:");
screen->displayMessageLine("1-View my balance");
screen->displayMessageLine("2-Withdraw cash");
screen->displayMessageLine("3-Deposit funds");
screen->displayMessageLine("4-Exit\n");
screen->displayMessageLine("Enter a choice ");
return keypad->getInput();
}
Transaction*createTransaction(int type)
{
switch (type)
{
case BALANCE_INQUIRY:
tmp = new BalanceInquiry(currentAccountNumber,*screen, *bankDatabase);
break;
case WITHDRAWAL:
break;
}
return tmp;
}
};