C++ C++;在向量中查找对象并调用其上的成员函数

C++ C++;在向量中查找对象并调用其上的成员函数,c++,vector,find,C++,Vector,Find,这与家庭作业有关,所以我必须使用向量来存储这些对象。 我有一个带有派生CheckingAccount和SavingsAccount的基类银行帐户 我询问用户希望为哪个帐户输入数据,即支票或储蓄,然后询问余额和利率/交易费。然后,使用switch语句,使用这些输入初始化对象,并使用智能指针将其添加到vectorvectorcount\u列表中 接下来,我要求用户通过添加成员函数credit或debit的交易(从基类重写为支票中的交易费用或储蓄中的利率),来选择与之交互的账户类型 我的问题在于:根据

这与家庭作业有关,所以我必须使用向量来存储这些对象。 我有一个带有派生CheckingAccount和SavingsAccount的基类银行帐户

我询问用户希望为哪个帐户输入数据,即支票或储蓄,然后询问余额和利率/交易费。然后,使用switch语句,使用这些输入初始化对象,并使用智能指针将其添加到vector
vectorcount\u列表中

接下来,我要求用户通过添加成员函数
credit
debit
的交易(从基类重写为支票中的交易费用或储蓄中的利率),来选择与之交互的账户类型

我的问题在于:根据用户选择的路径,两个帐户都会按照用户选择的顺序添加,因此我不知道对象在向量中的位置

#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;
}
这样添加帐户(在交换机情况下):

这是下面的整个程序。我仍然会遇到以下错误:

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
错误:对“HasIdentifier”类型的对象的调用没有匹配函数
如果(uuu pred(*uuuu first))
^~~~~~
…/WA4_2/main.cpp:230:19:注意:在函数模板专门化的实例化中,此处请求“std::_1::find_if.”
itElem=std::find_if(account_list.begin()、account_list.end()、HasIdentifier(account_choice));
^
…/WA4_2/main.cpp:169:8:注意:候选函数不可行:没有已知的从第一个参数的“std::u 1::shared_ptr”到“const BankAccount”的转换
布尔运算符()(常量银行帐户和c)常量
我真的不知道该怎么办。如果HasIdentifier不起作用,则意味着要在向量中搜索任何对象的标识符

#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;
}
#包括
#包括
#包括
//银行帐户类别
将BankAccount{//余额分类为双重保护成员,以便子类可以访问
受保护的:
双平衡=0;
std::string account_name=“?”;
公众:
银行账户(){};
~BankAccount(){};
银行账户(双用户余额,标准::字符串名称){
如果(userBalance>=0){//构造函数接收初始余额并使用它初始化余额
余额=用户余额;
}否则{
balance=0;//验证balance大于或等于0,否则显示错误并将balance设置为0
标准::cout
余额){//银行帐户的余额。如果有,余额应保持不变,函数应打印消息
std::cout账户名称;
}
布尔运算符==(常量银行帐户和比较)常量{
返回此->帐户名称==compare.account\u名称;
}
};
类SavingsAccount:PublicBankAccount{//继承银行帐户类以创建储蓄帐户
双酯=0;
获取初始余额和利率的公共构造函数
SavingsAccount(双用户余额,const std::string&name,双用户费率):BankAccount(用户余额,name),
利率(用户利率){
利率=用户利率;
}
双重的
calculateInterest(){//calculateInterest,返回一个双精度值,指示帐户赚取的利息金额
double earnings=0;//此金额通过利率乘以银行账户余额计算得出
双a=0;
a=getBalance();
收益=a*利率;
收益;
}
无效信用证(双倍金额){
余额+=金额+
calculateInterest();//成员函数credit应向当前余额中添加一个金额。
}
};
类别检查账户:公共银行账户{
双重交易费;
公众:
CheckingAccount(双重用户余额,常量标准::字符串和名称,双重输入):BankAccount(用户余额,名称),
交易费(
transfee_输入){
交易费=交易费输入;
}
无效信用证(双倍金额){
余额+=金额+交易费;//会员功能积分应向当前余额中添加金额。
}
无效借记(双倍金额){//会员功能借记应从银行账户中提款,并确保借记金额不超过
如果(金额>
getBalance()){//银行帐户的余额。如果是,余额应该保持不变,函数应该打印消息

std::cout迭代器本身的行为类似于指针(即:它们的接口被设计为类似于指针),因此,如果您有一个向量迭代器,并且希望对底层对象调用一个方法,那么您就“好像”迭代器是指向所讨论对象的指针

struct my_struct {
    int val;
    double other;
    void func() {}
};

int main() {
    std::vector<my_struct> my_structs = /*...*/;

    std::vector<my_struct>::iterator it = std::find_if(my_structs.begin(), my_structs.end(), [](my_struct const& m) {return m.val == 5;});

    it->func();
}
我不知道
HasIdentifier
是什么,也不知道它应该做什么:基于这种语法,我非常担心它是潜在bug的另一个来源。但有可能这部分代码编写正确,而且在没有看到它是如何实现的情况下,我无法对其进行分析。无论如何,我提出的调整都是错误的请修复此错误

编辑:好的。
有标识符
。这是一个非常简单的修复方法:如果
的形式应该是
bool operator()(T T)const
,或者
bool operator()(T const&T)cons,则由
find\u调用的functor的签名
#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;
}
struct my_struct {
    int val;
    double other;
    void func() {}
};

int main() {
    std::vector<my_struct> my_structs = /*...*/;

    std::vector<my_struct>::iterator it = std::find_if(my_structs.begin(), my_structs.end(), [](my_struct const& m) {return m.val == 5;});

    it->func();
}
std::vector<std::shared_ptr<BankAccount>>::iterator
itElem = std::find_if(account_list.begin(), account_list.end(), HasIdentifier(account_choice));
(**itElim).debit(amount);
//OR...
itElim->get()->debit(amount);
class HasIdentifier //No need to inherit from unary_function; it's been removed from C++17 anyways
{
public:
    HasIdentifier(string id) : 
    m_id(std::move(id)) //You're passing by value anyways, so move-constructing m_id 
    //will improve performance, especially if it's a large string.
    {}

    bool operator()(std::shared_ptr<BankAccount> const& c)const
    {
        return (c->getName() == m_id);
    }
private:
    string m_id;
};