Skip to content

Instantly share code, notes, and snippets.

/Account.cpp Secret

Created November 23, 2014 20:18
Show Gist options
  • Save anonymous/7c689940992f5986f51e to your computer and use it in GitHub Desktop.
Save anonymous/7c689940992f5986f51e to your computer and use it in GitHub Desktop.
Stack Overflow - Vector Erase bug
#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;
}
#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 */
#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;
}
}
#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
#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;
}
#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 */
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
#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;
}
}
}
#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;
}
#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