This is homework related, so I must use a vector to store these objects. I have a base class BankAccount with derived CheckingAccount and SavingsAccount
I ask the user which account they want to input data for, i.e. Checking or savings and then ask for balance and interest rate/transaction fee. Then, using a switch statement, the object is initialized using these inputs and added to the vector vector<shared_ptr<BankAccount>>account_list
using a smart pointer.
Next, I ask the user to pick an account type to interact with by adding a transaction of member function credit
or debit
(overridden from base class to account for a transaction fee in checking or interest rate in savings).
My problem lies here: Depending on the route the user took, either account would have been added in the order that the user chose, so I don't know the position of the object in the vector.
Accounts are added as such (in a switch case):
cout << "\nEnter a unique name for this savings account: \t";
cin >> name_input;
cout << "\nEnter your initial balance: \t" << endl;
cin >> balanceInput;
cout << "\nEnter your interest rate: \t" << endl;
cin >> interestRate_input;
account_list.push_back(new SavingsAccount(balanceInput,name_input,interestRate_input)); //create savings account object
cout << "\nAccount created successfully" << endl;
How can I first find, in a vector of two objects, the type CheckingAccount or type SavingsAccount, then knowing the elements position, call the appropriate member function on it?
This is what I have so far, so excuse any messy code where I was experimenting and trying to figure things out. for example:
cout << "\nEnter the amount to debit: \t" << endl;
cin >> amount;
//this might work but I don't know if this is where the relevant account resides
account_list[0]->debit(amount);
//here I don't know how to use the element once it is found to call a function on it
vector<shared_ptr<BankAccount>>::iterator
itElem = find_if(account_list.begin(), account_list.end(), HasIdentifier(account_choice));
account_list.itElem -> debit(amount);
//the line above this doesn't work
In the base class I created a string accountName
so each account had a unique ID.
Here is the HasIdentifier class that was created for the find_if to search by account name.
class HasIdentifier:public unary_function<BankAccount, bool>
{
public:
HasIdentifier(string id) : m_id(id) { }
bool operator()(const BankAccount& c)const
{
return (c.getName() == m_id);
}
private:
string m_id;
};
This is the entire program below. I am still getting these errors:
error: no matching function for call to object of type 'HasIdentifier'
if (__pred(*__first))
^~~~~~
.../WA4_2/main.cpp:230:19: note: in instantiation of function template specialization 'std::__1::find_if<std::__1::__wrap_iter<std::__1::shared_ptr<BankAccount> *>, HasIdentifier>' requested here
itElem = std::find_if(account_list.begin(), account_list.end(), HasIdentifier(account_choice));
^
.../WA4_2/main.cpp:169:8: note: candidate function not viable: no known conversion from 'std::__1::shared_ptr<BankAccount>' to 'const BankAccount' for 1st argument
bool operator()(const BankAccount& c)const
I'm not really sure what to do here. If HasIdentifier doesn't work, it was meant to bring the identifier of any object in to be searched for in the vector.
#include <iostream>
#include <vector>
#include <algorithm>
// class for bank account
class BankAccount { //balance as double protected member so child classes can access
protected:
double balance = 0;
std::string account_name = "???";
public:
BankAccount() {};
~BankAccount() {};
BankAccount(double userBalance, std::string name) {
if (userBalance >= 0) { // constructor to receive initial balance and use it to initialize the balance
balance = userBalance;
} else {
balance = 0; //verify balance is greater than or equal to 0, else display error and set balance to 0
std::cout << "\nError, balance set to 0\n";
}
account_name=name;
}
const std::string &getAccount_name() const {
return account_name;
}
void setAccount_name(const std::string &account_name) {
BankAccount::account_name = account_name;
};
virtual void
credit(double amount) { // Member function credit should add an amount to the current balance.
balance += amount;
}
virtual void
debit(double amount) { // Member function debit should withdraw money from the Bank-Account and ensure that the debit amount does not exceed
if (amount >
balance) { // the Bank-Account’s balance. If it does, the balance should be left unchanged and the function should print the message
std::cout << "The balance is less than the debit amount.\n"; // “The balance is less than the debit amount.”
} else {
balance -= amount;
}
}
virtual double getBalance() { // Member function getBalance should return the current balance.
return balance;
};
std::string getName()const {
return this->account_name;
}
bool operator ==(const BankAccount& compare) const{
return this->account_name == compare.account_name;
}
};
class SavingsAccount : public BankAccount { // inherit bank account class to create savings account
double interestRate = 0;
public: // constructor to get initial balance and interest rate
SavingsAccount(double userBalance, const std::string &name, double user_rate) : BankAccount(userBalance, name),
interestRate(user_rate) {
interestRate = user_rate;
}
double
calculateInterest() { // calculateInterest that returns a double indicating the amount of interest earned by an account
double earnings = 0; // this amount is calc by multiplying the interest rate by the bank account balance
double a = 0;
a = getBalance();
earnings = a * interestRate;
return earnings;
}
void credit(double amount) {
balance += amount +
calculateInterest(); // Member function credit should add an amount to the current balance.
}
};
class CheckingAccount : public BankAccount {
double transactionFee;
public:
CheckingAccount(double userBalance, const std::string &name, double transfee_input) : BankAccount(userBalance, name),
transactionFee(
transfee_input) {
transactionFee=transfee_input;
}
void credit(double amount) {
balance += amount + transactionFee; // Member function credit should add an amount to the current balance.
}
void debit(double amount) { // Member function debit should withdraw money from the Bank-Account and ensure that the debit amount does not exceed
if (amount >
getBalance()) { // the Bank-Account’s balance. If it does, the balance should be left unchanged and the function should print the message
std::cout << "The balance is less than the debit amount.\n"; // “The balance is less than the debit amount.”
} else {
balance -= amount + transactionFee;
}
}
};
class HasIdentifier:public std::unary_function<BankAccount, bool>
{
public:
HasIdentifier(std::string id) : m_id(id) { }
bool operator()(const BankAccount& c)const
{
return (c.getName() == m_id);
}
private:
std::string m_id;
};
int main() {
double balanceInput{0}; //variables for getting balance/interest inputs/outputs
double balanceOutput{0};
double interestRate_input{0};
double fee_input{0};
std::string name_input = "???";
std::vector<std::shared_ptr<BankAccount>>account_list; //storage for accounts
std::cout << "\nWhat type of account would you like to input? "
<< "\nSavings (1)"
<< "\nChecking (2)"
<< "\nEnter your choice:\t"
<< std::endl;
int choice{0};
std::cin >> choice;
switch(choice) {
case 1: { //savings input
std::cout << "\nEnter a unique name for this savings account: \t";
std::cin >> name_input;
std::cout << "\nEnter your initial balance: \t" << std::endl;
std::cin >> balanceInput;
std::cout << "\nEnter your interest rate: \t" << std::endl;
std::cin >> interestRate_input;
account_list.emplace_back(new SavingsAccount(balanceInput, name_input,
interestRate_input)); //create savings account object
std::cout << "\nAccount created successfully" << std::endl;
break;
}
case 2: {
std::cout << "\nEnter a unique name for this checking account: \t";
std::cin >> name_input;
std::cout << "\nEnter your initial balance: \t" << std::endl; //checking account input
std::cin >> balanceInput;
std::cout << "\nEnter the transaction fee: \t" << std::endl;
std::cin >> fee_input;
account_list.emplace_back(new CheckingAccount(balanceInput, name_input,fee_input)); //create checking account object
std::cout << "\nAccount created successfully" << std::endl;
break;
}
default: {
std::cout << "\nInvalid entry" << std::endl;
break;
}
}
std::cout << "\nTo enter a transaction for your account,"
<< "\nplease enter the account name: \t";
std::string account_choice="???";
std::cin >> account_choice;
std::vector<std::shared_ptr<BankAccount>>::iterator
itElem = std::find_if(account_list.begin(), account_list.end(), HasIdentifier(account_choice));
std::cout << "\nWould you like to process a (d)ebit or (c)redit to the account?" << std::endl;
int a = 0;
tolower(a);
std::cin >> a;
double amount{0};
switch (a){
case 'd': //debit the account
std::cout << "\nEnter the amount to debit: \t" << std::endl;
std::cin >> amount;
(**itElem).debit(amount);
break;
case 'c': //credit the account
std::cout << "\nEnter the amount to credit: \t" << std::endl;
std::cin >> amount;
(**itElem).credit(amount);
break;
default:
std::cout << "\nInvalid entry" << std::endl;
}
return 0;
}