-
-
Save anonymous/7c689940992f5986f51e to your computer and use it in GitHub Desktop.
Stack Overflow - Vector Erase bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Account.h" | |
/** | |
* Account Class (base) | |
*/ | |
/* | |
* Constructor. | |
* | |
* int id The account's ID in the database. | |
* int userId The account holder's ID in the database. | |
* double balance Optional: The initial balance of the account. | |
* string name The account's given name. | |
*/ | |
Account::Account (int id, int userId, double balance, std::string name) | |
{ | |
m_id = id; | |
m_userId = userId; | |
m_balance = balance; | |
m_name = name; | |
m_type = ACCT; | |
} | |
/* | |
* Deconstructor. | |
*/ | |
Account::~Account () | |
{ | |
// Free any allocated memory. | |
} | |
/** | |
* Gets the account ID. | |
*/ | |
int Account::getId () const | |
{ | |
return m_id; | |
} | |
/* | |
* Prints out details on the account. | |
*/ | |
std::string Account::getDetails () const | |
{ | |
std::string type; | |
if (m_type == CHEQ) type = "[C]"; | |
else if (m_type == SAVE) type = "[S]"; | |
else type = "[A]"; | |
return "Account #" + std::to_string(getId()) + " " + type + " " | |
+ getName() + " $" + std::to_string(getBalance()); | |
} | |
/** | |
* Gets the account holder's ID. | |
* | |
* @return int The account holder's ID. | |
*/ | |
int Account::getUserId () const | |
{ | |
return m_userId; | |
} | |
/** | |
* Gets the account's balance. | |
*/ | |
double Account::getBalance () const | |
{ | |
return m_balance; | |
} | |
/** | |
* Gets the account's name. | |
*/ | |
std::string Account::getName () const | |
{ | |
return m_name; | |
} | |
/** | |
* Gets the account's type. | |
* | |
* @return string The account's type. | |
*/ | |
int Account::getType () const | |
{ | |
return m_type; | |
} | |
/** | |
* Gets the account's transaction history. | |
* | |
* Returns a string vector of the account's transaction history. | |
*/ | |
std::vector<std::string> Account::getHistory () const | |
{ | |
return m_history; | |
} | |
/** | |
* Sets the account name. | |
* | |
* string name The name of the account | |
*/ | |
void Account::setName (std::string name) | |
{ | |
m_name = name; | |
} | |
/** | |
* Withdraws funds from the account. | |
* | |
* double amount The dollar amount being withdrawn. | |
* | |
* Returns true on a successful withdrawal | |
*/ | |
bool Account::withdrawFunds (double amount) | |
{ | |
// If there are sufficient funds. | |
if (m_balance - amount > 0) | |
{ | |
// Withdraw the specified amount. | |
m_balance -= amount; | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Deposits funds into the account. | |
* | |
* double amount The dollar amount being deposited. | |
*/ | |
void Account::depositFunds (double amount) | |
{ | |
m_balance += amount; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef ACCOUNT_H | |
#define ACCOUNT_H | |
#include <string> | |
#include <vector> | |
#include <iostream> | |
#define ACCT 0 // Generic account | |
#define CHEQ 1 // Chequing account | |
#define SAVE 2 // Savings account | |
/* | |
* Generic account type | |
*/ | |
class Account | |
{ | |
protected: | |
int m_id, m_userId, m_type; | |
double m_balance; | |
std::string m_name; | |
std::vector<std::string> m_history; | |
public: | |
Account (int id, int userId, double balance = 0, | |
std::string name = ""); | |
virtual ~Account (); | |
// Accessor Methods. | |
int getId () const; | |
int getUserId () const; | |
int getType () const; | |
double getBalance () const; | |
std::string getName () const; | |
std::string getDetails () const; | |
std::vector<std::string> getHistory () const; | |
// Mutator Methods. | |
void setName (std::string name); | |
void depositFunds (double amount); | |
virtual bool withdrawFunds (double amount); | |
}; | |
/* | |
* Chequing account type | |
*/ | |
class ChequingAccount : public Account | |
{ | |
public: | |
ChequingAccount (int id, int userId, double balance = 0, | |
std::string name = "") : | |
Account(id, userId, balance, name) | |
{ | |
// Chequing account type. | |
m_type = CHEQ; | |
// If no name was given. | |
if (name == "") | |
{ | |
// Give account a generic name. | |
m_name = "Chequing Account #" + std::to_string(id); | |
} | |
else | |
{ | |
m_name = name; | |
} | |
} | |
~ChequingAccount () | |
{ | |
} | |
virtual bool withdrawFunds (double amount); | |
}; | |
/* | |
* Savings account type | |
*/ | |
class SavingsAccount : public Account | |
{ | |
public: | |
SavingsAccount (int id, int userId, double balance, std::string name) : | |
Account(id, userId, balance, name) | |
{ | |
// Savings account type. | |
m_type = SAVE; | |
// If no name was given. | |
if (name == "") | |
{ | |
// Give account a generic name. | |
m_name = "Savings Account #" + std::to_string(id); | |
} | |
else | |
{ | |
m_name = name; | |
} | |
} | |
~SavingsAccount () | |
{ | |
} | |
}; | |
#endif /* ACCOUNT_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Bank.h" | |
#include <iostream> | |
using namespace std; | |
/* | |
* Constructor. | |
*/ | |
Bank::Bank () | |
{ | |
m_accountCounter = 0; | |
m_userCounter = 0; | |
} | |
/* | |
* Deconstructor. | |
*/ | |
Bank::~Bank () | |
{ | |
// Destroy all accounts. | |
int numAcct = m_acctDb.getDatabase().size(); | |
for (int i = 0; i < numAcct; ++i) delete m_acctDb.getDatabase()[i]; | |
// Destroy all users. | |
int numUser = m_userDb.getDatabase().size(); | |
for (int i = 0; i < numUser; ++i) delete m_userDb.getDatabase()[i]; | |
} | |
/* | |
* Get the current accountID counter. | |
*/ | |
int Bank::getAccountCounter () const | |
{ | |
return m_accountCounter; | |
} | |
/* | |
* Get the current userID counter. | |
*/ | |
int Bank::getUserCounter () const | |
{ | |
return m_userCounter; | |
} | |
/* | |
* Returns the number of accounts in the bank database. | |
*/ | |
int Bank::getNumAccounts () const | |
{ | |
return (int) m_acctDb.getDatabase().size(); | |
} | |
/* | |
* Returns the number of users in the bank database. | |
*/ | |
int Bank::getNumUsers () const | |
{ | |
return (int) m_userDb.getDatabase().size(); | |
} | |
/* | |
* Gets the account database. | |
*/ | |
Database<Account> Bank::getAccountDatabase () const | |
{ | |
return m_acctDb; | |
} | |
/* | |
* Gets the user database. | |
*/ | |
Database<User> Bank::getUserDatabase () const | |
{ | |
return m_userDb; | |
} | |
/* | |
* Gets the specified bank account from the database. | |
*/ | |
Account *Bank::getAccount (int accountId) | |
{ | |
std::vector<Account*> db = m_acctDb.getDatabase(); | |
std::vector<Account*>::iterator it = db.begin(); | |
while (it != db.end()) | |
{ | |
if ((*it)->getId() == accountId) | |
{ | |
// Return the selected account. | |
return (*it); | |
} | |
else ++it; | |
} | |
return NULL; | |
} | |
/* | |
* Gets the specified user from the database. | |
*/ | |
User *Bank::getUser (int userId) | |
{ | |
std::vector<User*> db = m_userDb.getDatabase(); | |
std::vector<User*>::iterator it = db.begin(); | |
while (it != db.end()) | |
{ | |
if ((*it)->getId() == userId) | |
{ | |
// Return the selected user. | |
return (*it); | |
} | |
} | |
return NULL; | |
} | |
/* | |
* Adds a new chequing account to the bank database. | |
*/ | |
void Bank::addChequing (int userId, double balance, std::string name) | |
{ | |
m_acctDb.add(new ChequingAccount(++m_accountCounter, userId, balance, name)); | |
} | |
/* | |
* Adds a new savings account to the bank database. | |
*/ | |
void Bank::addSavings (int userId, double balance, std::string name) | |
{ | |
m_acctDb.add(new SavingsAccount(++m_accountCounter, userId, balance, name)); | |
} | |
/* | |
* Adds a new customer to the bank database. | |
*/ | |
void Bank::addCustomer (std::string firstName, std::string lastName, | |
std::string password, std::string username = NULL) | |
{ | |
m_userDb.add(new Customer(++m_userCounter, password, firstName, lastName, username)); | |
} | |
/* | |
* Add a new manager to the bank database. | |
*/ | |
void Bank::addManager (std::string firstName, std::string lastName, | |
std::string password, std::string username = NULL) | |
{ | |
m_userDb.add(new Manager(++m_userCounter, password, firstName, lastName, username)); | |
} | |
/* | |
* Add a new maintenance user to the bank database. | |
*/ | |
void Bank::addMaintenance (std::string firstName, std::string lastName, | |
std::string password, std::string username = NULL) | |
{ | |
m_userDb.add(new Maintenance(++m_userCounter, password, firstName, lastName, username)); | |
} | |
/* | |
* Deletes the specified account from the bank database. | |
*/ | |
void Bank::deleteAccount (int accountId) | |
{ | |
std::vector<Account*> db = m_acctDb.getDatabase(); | |
std::vector<Account*>::iterator it = db.begin(); | |
cout << "Searching for account " << accountId << endl; | |
while (it != db.end()) | |
{ | |
if ((*it)->getId() == accountId) | |
{ | |
cout << "Found account 1" << endl; | |
// Delete selected account. | |
delete (*it); | |
it = db.erase(db.begin()); | |
} | |
else ++it; | |
} | |
} | |
/* | |
* Deletes the specified user from the bank database. | |
*/ | |
void Bank::deleteUser (int userId) | |
{ | |
std::vector<User*> db = m_userDb.getDatabase(); | |
std::vector<User*>::iterator it = db.begin(); | |
while (it != db.end()) | |
{ | |
if ((*it)->getId() == userId) | |
{ | |
// Delete selected user. | |
delete *it; | |
it = db.erase(it); | |
} | |
else ++it; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BANK_H_ | |
#define BANK_H_ | |
#include "Database.h" | |
class Bank | |
{ | |
private: | |
Database<Account> m_acctDb; | |
Database<User> m_userDb; | |
int m_accountCounter; | |
int m_userCounter; | |
public: | |
Bank (); | |
~Bank (); | |
// Accessor Methods. | |
int getAccountCounter () const; | |
int getUserCounter () const; | |
int getNumAccounts () const; | |
int getNumUsers () const; | |
Database<Account> getAccountDatabase () const; | |
Database<User> getUserDatabase () const; | |
User *getUser (int userId); | |
Account *getAccount (int accountId); | |
std::vector<ChequingAccount> getChequingAccounts () const; | |
std::vector<SavingsAccount> getSavingsAccounts () const; | |
std::vector<Manager> getManagers () const; | |
std::vector<Customer> getCustomers () const; | |
std::vector<Maintenance> getMaintenance () const; | |
// Mutator Methods. | |
void addChequing (int userId, double balance = 0, std::string name = | |
""); | |
void addSavings (int userId, double balance = 0, | |
std::string name = ""); | |
void addCustomer (std::string firstName, std::string lastName, | |
std::string password, std::string username); | |
void addManager (std::string firstName, std::string lastName, | |
std::string password, std::string username); | |
void addMaintenance (std::string firstName, std::string lastName, | |
std::string password, std::string username); | |
void deleteAccount (int accountId); | |
void deleteUser (int userId); | |
}; | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Account.h" | |
/** | |
* Withdraws funds from account. Issues a $2 fee if account balance drops below $1000. | |
* | |
* double amount The dollar amount being withdrawn. | |
*/ | |
bool ChequingAccount::withdrawFunds (double amount) | |
{ | |
// If the account has enough for the withdraw operation. | |
if (m_balance - amount > 0) | |
{ | |
// If the new balance is below $1000, warn the user. | |
if (m_balance - amount < 1000) | |
{ | |
std::string response; | |
while (true) | |
{ | |
std::cout | |
<< "WARNING: " + m_name | |
+ "'s balance will be below $1000, " | |
"a $2 transaction fee will be applied.\n\n" | |
"Do you wish to continue? [Y/N]" | |
<< std::endl; | |
std::cin >> response; | |
// If the fee was accepted. | |
if (response == "y" || response == "Y") | |
{ | |
// Apply transaction fee. | |
m_balance -= 2; | |
break; | |
} | |
// If the fee was rejected. | |
else if (response == "n" || response == "N") | |
{ | |
return false; | |
} | |
// Invalid command. | |
else | |
{ | |
std::cout << "Invalid command." << std::endl; | |
} | |
} | |
} | |
// Withdraw funds from account. | |
m_balance -= amount; | |
return true; | |
} | |
// Not enough funds for transaction. | |
return false; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DATABASE_H | |
#define DATABASE_H | |
#include <vector> | |
#include <typeinfo> | |
#include <algorithm> | |
#include "Account.h" | |
#include "User.h" | |
template<class T> | |
class Database | |
{ | |
protected: | |
std::vector<T*> m_database; | |
public: | |
Database (); | |
virtual ~Database (); | |
std::vector<T*> getDatabase () const; | |
void add (T *Object); | |
bool del (int id); | |
}; | |
/* | |
* Constructor | |
*/ | |
template<class T> | |
Database<T>::Database () | |
{ | |
// Initialize the database. | |
} | |
/* | |
* Deconstructor. | |
*/ | |
template<class T> | |
Database<T>::~Database () | |
{ | |
// Free any allocated memory. | |
} | |
/* | |
* Returns the vector. | |
*/ | |
template<class T> | |
std::vector<T*> Database<T>::getDatabase () const | |
{ | |
return m_database; | |
} | |
/* | |
* Adds a new object to the database. | |
*/ | |
template<class T> | |
void Database<T>::add (T *object) | |
{ | |
m_database.push_back(object); | |
} | |
#endif /* DATABASE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
test: test.o | |
g++ -Wall -std=c++11 -g test.o Account.o User.o ChequingAccount.o Bank.o -o test | |
test.o: Account.cpp Bank.cpp ChequingAccount.cpp User.cpp Bank.h Account.h User.h Database.h | |
g++ -Wall -std=c++11 -g -c test.cpp Account.cpp Bank.cpp ChequingAccount.cpp User.cpp | |
clean: | |
rm -rf *.o *.gch test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Bank.h" | |
#include <iostream> | |
using namespace std; | |
int main () | |
{ | |
Bank bank; | |
cout << "Num accounts in bank: " << bank.getNumAccounts() << endl << endl; | |
cout << "Adding accounts to bank..." << endl; | |
bank.addChequing(1, 1500.0, "testchq"); | |
bank.addSavings(1, 2000.0, "testsav"); | |
cout << "Num accounts in bank: " << bank.getNumAccounts() << endl; | |
for (int i = 0; i < bank.getNumAccounts(); ++i) | |
{ | |
if (bank.getAccount(i + 1) == NULL) cout << "Account is NULL" << endl; | |
else | |
{ | |
cout << bank.getAccount(i + 1)->getDetails() << endl; | |
} | |
} | |
cout << endl; | |
cout << "Deleting account 1..." << endl; | |
bank.deleteAccount(1); | |
cout << endl; | |
cout << "Num accounts in bank: " << bank.getNumAccounts() << endl; | |
for (int i = 0; i < bank.getNumAccounts(); ++i) | |
{ | |
if (bank.getAccount(i + 1) == NULL) cout << "Account is NULL" << endl; | |
else | |
{ | |
cout << bank.getAccount(i + 1)->getDetails() << endl; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "User.h" | |
/* | |
* Constuctor. | |
* | |
* int id The user's ID in the database. | |
* string role The user's role (Customer, Manager or Maintenance) | |
* string firstName The user's first name. | |
* string lastName The user's last name. | |
* string password The user's password. | |
* string userName Optional: The user's username. | |
*/ | |
User::User (int id, std::string password, std::string firstName, | |
std::string lastName, std::string username = NULL) | |
{ | |
m_id = id; | |
m_role = USER; | |
m_password = password; | |
m_firstName = firstName; | |
m_lastName = lastName; | |
m_username = username; | |
} | |
/* | |
* Deconstructor | |
*/ | |
User::~User () | |
{ | |
// Free any memory allocated. | |
} | |
/* | |
* Gets the user id. | |
*/ | |
int User::getId () const | |
{ | |
return m_id; | |
} | |
/* | |
* Gets the user's role. | |
*/ | |
int User::getRole () const | |
{ | |
return m_role; | |
} | |
/* | |
* Gets the user's first name | |
*/ | |
std::string User::getFirstName () const | |
{ | |
return m_firstName; | |
} | |
/* | |
* Gets the user's last name | |
*/ | |
std::string User::getLastName () const | |
{ | |
return m_lastName; | |
} | |
/* | |
* Gets the user's username | |
*/ | |
std::string User::getUsername () const | |
{ | |
return m_username; | |
} | |
/* | |
* Gets the user's password | |
*/ | |
std::string User::getPassword () const | |
{ | |
return m_password; | |
} | |
/* | |
* Gets the user's password | |
*/ | |
std::string User::getDetails () const | |
{ | |
std::string role; | |
if (getRole() == CUST) role = "[C]"; | |
if (getRole() == MNGR) role = "[M]"; | |
if (getRole() == MAIN) role = "[X]"; | |
return "User #" + std::to_string(getId()) + "\t" + role + " " | |
+ getFirstName() + " " + getLastName() + " <" + getUsername() | |
+ ">"; | |
} | |
/* | |
* Sets the user's first name. | |
*/ | |
void User::setFirstName (std::string firstName) | |
{ | |
m_firstName = firstName; | |
} | |
/* | |
* Sets the user's last name. | |
*/ | |
void User::setLastName (std::string lastName) | |
{ | |
m_lastName = lastName; | |
} | |
/* | |
* Sets the user's username. | |
*/ | |
void User::setUsername (std::string username) | |
{ | |
m_username = username; | |
} | |
/* | |
* Sets the user's password. | |
*/ | |
void User::setPassword (std::string oldPassword, std::string newPassword) | |
{ | |
m_password = newPassword; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef USER_H | |
#define USER_H | |
#include <string> | |
#define USER 0 | |
#define MNGR 1 | |
#define MAIN 2 | |
#define CUST 3 | |
/* | |
* Generic User type. | |
*/ | |
class User | |
{ | |
protected: | |
int m_id, m_role; | |
std::string m_firstName, m_lastName, m_username, m_password; | |
public: | |
User (int id, std::string password, std::string firstName, | |
std::string lastName, std::string username); | |
virtual ~User (); | |
// Accessor Methods. | |
int getId () const; | |
int getRole () const; | |
std::string getFirstName () const; | |
std::string getLastName () const; | |
std::string getUsername () const; | |
std::string getPassword () const; | |
std::string getDetails () const; | |
// Mutator Methods. | |
void setFirstName (std::string firstName); | |
void setLastName (std::string lastName); | |
void setUsername (std::string username); | |
void setPassword (std::string oldPassword, std::string newPassword); | |
}; | |
/* | |
* Manager user type. | |
*/ | |
class Manager : public User | |
{ | |
public: | |
Manager (int id, std::string password, std::string firstName, | |
std::string lastName, std::string username = NULL) : | |
User(id, password, firstName, lastName, username) | |
{ | |
m_role = MNGR; | |
} | |
}; | |
/* | |
* Customer user type. | |
*/ | |
class Customer : public User | |
{ | |
public: | |
Customer (int id, std::string password, std::string firstName, | |
std::string lastName, std::string username = NULL) : | |
User(id, password, firstName, lastName, username) | |
{ | |
m_role = CUST; | |
} | |
}; | |
/* | |
* Maintenance user type. | |
*/ | |
class Maintenance : public User | |
{ | |
public: | |
Maintenance (int id, std::string password, std::string firstName, | |
std::string lastName, std::string username = NULL) : | |
User(id, password, firstName, lastName, username) | |
{ | |
m_role = MAIN; | |
} | |
}; | |
#endif /* USER_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment