2016-04-29 14 views
2

私は、銀行、勘定、セーブ、およびチェックの4つのクラスを持っています。保存と確認の両方がアカウントから公開されています。私は2つの仮想void関数をAccountに持っています。出し入れ。問題は残りのコードでは繰り返されるため、私は預金貯金機能のコードを投稿しています。多型の誤解C++

私は銀行口座タイプのベクトルにアカウントを追加する機能を銀行クラスに持っています。貯蓄オブジェクトのデポジット機能を呼び出すたびに、アカウントのデポジット機能が使用され、保存されません(デバッガを使用して検出されます)。

最初はポインタを使用していませんでしたが、このスレッドに進みました:Polymorphism misunderstanding/redefined virtual function not workingと仮想関数のポインタを使用する方法を学びました。

質問:Saving.cppで意図した "多態性"メソッドの代わりにAccount.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); 
} 
+3

私はそれを逃してしまったに違いありません...実際の質問はどこにも見たことがありません... –

+0

私は見た目を危険にさらし、またそれを逃したに違いありません。 @Raj、具体的にはあなたの質問は何ですか? – Bizmarck

+1

Bank :: addAccountにAccount by valueを渡すので、aという名前の変数は「スライスされます」(Savingオブジェクトの代わりにAccountとして扱われます)。それが問題なのかどうかはわかりません。 –

答えて

7

私はこれを行うコードが表示されませんが、質問はBankアカウント、すなわち、std::vector<account>ベクトルを持っていることを言います。その場合、問題は派生クラスのオブジェクトがベクトルにプッシュされたときにオブジェクトaccountにスライスされ、派生したものが失われることです。コードはaccountへのポインタまたは参照を使用する必要があります。通常、これはstd::vector<account*>またはstd::vector<std::unique_ptr<account>>で行われ、派生オブジェクトはnewで割り当てられます。コードでは、値ではなくポインタや参照によってaccountから派生した型のオブジェクトも渡す必要があります(たとえば、void Bank::addAccount(Account a)は呼び出された引数をスライスするため機能しません)。

+0

曖昧さを避けるために 'unique_ptr'を' std :: unique_ptr'に変更したいかもしれません。 – ArchbishopOfBanterbury

+0

@ArchbishopOfBanterbury - done。ありがとう。 –

+0

欠けている銀行のベクトルを指摘していただきありがとうございます。私はあなたの提案された修正で元のスレッドを更新しました。あなたの提案は私の問題を解決するようでした。 –

4

私は間違っていない場合は、あなたのコードのコピー・構築物中の2行ポリペプチドの関係を破壊し、Accountオブジェクトに挿入する。

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

bank_accounts.push_back(a); 

私はAccount*bank_accounts、スマートポインタの配列を作成することをお勧め。また、addAccountは参照(Account&)またはスマートポインタでなければなりません。

+0

お返事ありがとうございます。あなたとピート・ベッカーの答えの組み合わせで問題を解決できました。 –