I'm trying to write some c++ code that will perform a binary search on a vector of object pointers. For reference my program is like a bank account system where a user can open a bank account and make deposits/withdrawals on said bank account, which in turn create a new transaction object that is pushed back to a list of Transaction pointer objects like so: in main.cpp:
else if (userCommand == "withdraw")
{
try
{
int index;
float amount;
time_t currentTime = time(nullptr); //gets current time
cout << "Please pick the account you wish to withdraw from starting from 1: " << endl;
cin >> index;
if (index > allAccounts.size() || index <= 0) throw InvalidIndexException(); //0 is not an option for any other command other than withdraw so we include it for the exception
cout << "Please give the amount of money you wish to withdraw: " << endl;
cin >> amount;
if (amount < 0) throw NegativeValue("Withdrawal");
allAccounts[index - 1]->withdraw(amount);
Transaction* accountTransaction = new Transaction("Withdrawal", currentTime, amount); //creates new Transaction object that will be passed into the account object
allAccounts[index - 1]->addTransaction(accountTransaction);
}
catch (ExceedOverDraftException)
{
cout << "Current account overdraft exceeded" << endl;
}
catch (NegativeWithdrawalException)
{
cout << "Savings account cannot go below 0" << endl;
}
catch (InvalidIndexException)
{
cout << "Index given does not exist" << endl;
}
catch (NegativeValue e)
{
cout << e.getMessage() << endl;
}
}
else if (userCommand == "deposit")
{
try
{
int index;
float amount;
time_t currentTime = time(nullptr);
cout << "Please pick the account you wish deposit to starting from 1: " << endl;
cin >> index;
if (index > allAccounts.size() || index <= 0) throw InvalidIndexException();
cout << "Please give the amount of money you wish to deposit: " << endl;
cin >> amount;
if (amount < 0) throw NegativeValue("Deposit");
allAccounts[index - 1]->deposit(amount);
Transaction* accountTransaction = new Transaction("Deposit", currentTime, amount);
allAccounts[index - 1]->addTransaction(accountTransaction);
}
catch (InvalidIndexException)
{
cout << "Index does not exist" << endl;
}
catch (NegativeValue e)
{
cout << e.getMessage() << endl;
}
}
else if (userCommand == "search")
{
try
{
int index;
float valueAnswer;
int transactionsSize;
cout << "Please say which account you wish to search transaction for starting from 1" << endl;
cin >> index;
if (index > allAccounts.size()) throw InvalidIndexException();
transactionsSize = allAccounts[index - 1]->getHistorySize();
cout << "Please state what value you wish to search for" << endl;
cin >> valueAnswer;
cout << allAccounts[index - 1]->search(valueAnswer, 0, transactionsSize - 1);
}
catch (InvalidIndexException)
{
cout << "Index given does not exist";
}
catch (TransactionNotFound e)
{
cout << e.getMessage();
}
}
in account.cpp:
void Account::addTransaction(Transaction* t)
{
history.push_back(t); //as the vector is full of pointers the parameter must also be a pointer.
sort(history.begin(), history.end());
}
Transaction Account::search(float value, int start, int end) throw (TransactionNotFound) //search function is a binary search
{
if (start <= end)
{
for (int i = 0; i < history.size(); i++)
{
cout << history[i]->getValue() << endl;
}
int mid = (start + end) / 2; //midpoint of the vector
if (history[mid]->getValue() == value) return *history[mid];
else if (history[mid]->getValue() < value) return search(value, mid + 1, end);
else if (history[mid]->getValue() > value) return search(value, start, mid - 1);
}
else throw TransactionNotFound(value); //if the array has been searched to the point that start has reached the end the transaction doesn't exist
}
As you can see the main idea is that every time a new transaction is made, either from calling deposit or withdraw, an object of transaction is made which is then added to the vector and then should be sorted in ascending order. To sort I tried to follow a guide from an older stack overflow message that was using struct objects rather than class objects (Sorting a vector of custom objects) which seemed to use operator overloading of the < operator on the struct object that would then allow the vector of struct objects to be sorted, which I tried adapting in my transaction class as a friend function like so: in transaction.cpp:
bool operator <(const Transaction& t1, const Transaction& t2)
{
return (t1.value < t2.value); //checks if the next value in the vector is greater than the current value in the vector.
}
However, I have tested the sort method and it doesn't seem to be sorted the objects as I expect it to, in that it doesn't seem to be sorted the objects at all, causing my TransactionNotFound exception to be thrown. I'm genuinely not sure what I've done wrong, I'm assuming it is how I've done my operator overload, but I don't know what I need to do to fix it. Sorry if my code looks awful, I think I realised that my try and catch blocks could go outside the if statement. Also if there is any information about my code that might be needed please let me know, I'm new to stack overflow in general so I'm not sure if what I've included is needed or not. Any help people can give is really appreciated!