Ceci est lié aux devoirs, donc je dois utiliser un vecteur pour stocker ces objets. J'ai une classe de base BankAccount avec CheckingAccount et SavingsAccountC++ Rechercher un objet dans un vecteur et y appeler une fonction membre
Je demande à l'utilisateur le compte pour lequel il veut entrer des données, c'est-à-dire vérifier ou faire des économies, puis demander le solde et le taux d'intérêt/frais de transaction. Ensuite, en utilisant une instruction switch, l'objet est initialisé en utilisant ces entrées et ajouté au vecteur vector<shared_ptr<BankAccount>>account_list
en utilisant un pointeur intelligent. Ensuite, je demande à l'utilisateur de choisir un type de compte avec lequel interagir en ajoutant une transaction de la fonction membre credit
ou debit
(substituée à la classe de base pour tenir compte des frais de transaction en vérification ou du taux d'intérêt en épargne).
Mon problème est le suivant: Selon l'itinéraire emprunté par l'utilisateur, l'un ou l'autre compte aurait été ajouté dans l'ordre choisi par l'utilisateur, donc je ne connais pas la position de l'objet dans le vecteur.
comptes sont ajoutés en tant que tel (dans un boîtier de commutation):
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;
Comment puis-je trouver d'abord, dans un vecteur de deux objets, le type CheckingAccount ou tapez SavingsAccount, sachant alors la position des éléments, appel la fonction de membre appropriée sur elle?
C'est ce que j'ai jusqu'ici, donc excusez n'importe quel code désordonné où j'expérimentais et essayais de comprendre les choses. par exemple:
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
Dans la classe de base I créé un string accountName
de sorte que chaque compte avait un identifiant unique.
Voici la classe HasIdentifier qui a été créée pour find_if à rechercher par nom de compte.
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;
};
Voici l'intégralité du programme ci-dessous. Je reçois toujours ces erreurs:
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
Je ne sais pas quoi faire ici. Si HasIdentifier ne fonctionne pas, il était destiné à amener l'identifiant de tout objet à rechercher dans le vecteur.
#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;
}
@ RobertPrévost Pas un doublon de cela. Le problème est dû à la façon dont l'utilisateur utilise (de manière irresponsable) les pointeurs, et non au fonctionnement des itérateurs. – Xirema
Pourriez-vous suggérer un meilleur moyen d'utiliser des pointeurs? –