误解多态C ++

时间:2016-04-29 18:52:20

标签: c++ polymorphism

我有四个班级,银行,帐户,保存和检查。保存和检查都是从Account公开继承的。我在Account中有两个虚拟空函数;存款和取款。我只发布了存款存款功能的代码,因为其余代码的问题是重复的。

我的Bank类中有一个函数可以将帐户添加到account类型的向量中。每当我为存储对象调用存款函数时,它都使用Account的存款功能而不是保存(使用调试器找到)。

起初我没有使用指针,但是我经历了这个线程:Polymorphism misunderstanding / redefined virtual function not working并且学会了使用指针来实现虚函数。

问题:是什么导致我的代码使用Account.cpp中的默认虚拟方法而不是预期的"多态" Saving.cpp中的方法?我该如何解决?

Account.cpp

#pragma once
#include <string>
using std::string;
enum account_type { saving, checking };

class Account
{
public:
    Account();
    Account(int, account_type, double);
    ~Account();

    virtual void deposit(double&) {};
    virtual void withdraw(double&) {};
protected:
    int account_number;
    account_type type;
    double balance;

    int generateAccountNumber();
    double initializeBalance();
};

Saving.cpp

class Saving : public Account
{
public:
    Saving();
    Saving(int, account_type, double);
    ~Saving();

    void deposit(double&) //deposits some amount into a saving account
    {
        if (amount < 0)
            throw "Cannot withdraw an amount less than $0.00";
        else if (amount > balance)
            throw "Cannot withdraw an amount greater than the current balance";
        else
            balance -= amount;
    }
 private:
    const double interest_rate = 0.01;
};

Bank.cpp

class Bank
{
private:
    vector <Account*> bank_accounts;
    //ORIGINAL BEFORE FIX: vector <Account> bank_accounts;
public:
    void Bank::addAccount(Account a) //adds some account to a vector
    {
        bank_accounts.push_back(a);
    }

    Account * findAccount(int acc_num) //finds the account by it's account number
    { 
        int found = -1;
        for (int y = 1; y <= (int)bank_accounts.size(); y++) {
        if (acc_num == bank_accounts[y - 1].getAccountNumber())
            found = y - 1;
        }

         if (found == -1) {
             throw "\nAccount not found";
         }
        else
        {
            if (bank_accounts[found].getAccountType() == 0)
            {
                Account * saving = &bank_accounts[found];
                return saving;
            }
        else if (bank_accounts[found].getAccountType() == 1)
        {
                Account * checking = &bank_accounts[found];
                return checking;
        }
     }
  }
}

int main()
{
    Bank Swiss;
    Saving s(num, type, bal); // some user values for these variables
    Account * tempAccount1 = &s;
    Swiss.addAccount(*tempAccount1);
    Swiss.findAccount(num)->deposit(amt);
}

2 个答案:

答案 0 :(得分:7)

我没有看到执行此操作的代码,但问题是Bank有一个帐户向量,即std::vector<account>。如果是这种情况,问题是派生类对象在被推入向量时会被切成account个对象,并且它们会失去派生对象。代码需要使用指针或对account的引用。通常,这是使用std::vector<account*>std::vector<std::unique_ptr<account>>以及使用new分配的派生对象完成的。代码也应该通过指针或引用传递从account派生的类型的对象,而不是通过值传递(例如,void Bank::addAccount(Account a)将不起作用,因为它将切片调用它的参数)。

答案 1 :(得分:4)

如果我没有弄错的话,你的代码中的这两行会将a构造成Account对象,从而破坏多态关系。

    void Bank::addAccount(Account a) //adds some account to a vector

    bank_accounts.push_back(a);

我建议将bank_accounts和一系列智能指针发送到Account*addAccount也应该是引用(Account&)或智能指针。