0

OK、ポリモーフィズムと仮想関数は初めてで、最初の関数の呼び出しでさえ問題があります。これはエラーを返すため、問題は呼び出し自体にあると思います。

banking.cpp(289): error C2664: 'Checking::Balance' : cannot convert parameter 1 from 'Checking (__cdecl *)(void)' to 'Checking &'

これは、関数に間違ったものを渡していることを意味していると確信しています。仮想関数のクラスのインスタンスの名前を単に渡すことはできないこと、参照またはポインターとして渡す必要があることを知っています。両方の方法を試しましたが、同じエラーが発生しました。

これは銀行のプロジェクトであり、入力の検証には関係のないものがたくさんあるため、全体のコピーと貼り付けを省略しています。親クラスは「Account」で、「Checking」はそれから派生した子です。「checkingObject」は、呼び出そうとしているクラス「Checking」のインスタンスの名前です。

main .cpp での関数呼び出し:

Checking::Balance(&checkingObject);

Account.h (親クラス) で宣言:

virtual void Balance();

Checking.h (子クラス) で再宣言:

void Balance(Checking &);

Checking.cpp で定義されています (balance はクラスのプライベート メンバーです)。

void Checking::Balance(Checking &)
{
cout << balance;

}

私は何かが欠けているに違いありませんが、関数への参照としてオブジェクトのcheckingObjectを渡そうとしています。エラー メッセージの「cannot convert parameter 1 from 'Checking (__cdecl *)(void)' 」の部分がよくわかりません。ClassName &についての私の理解は、クラスから派生した任意のオブジェクトを取るということです。

編集: わかりやすくするために、より多くのコードを含めます。

bank.cpp (メインファイル)

Account accountObject();
    Checking checkingObject();
    Savings savingsObject();
int main()
{       
regScreen();
servicesScreen();   

return 0;
}

void checkingScreen()
{
system("cls");
int choice;

do
{
    string countString;     
    centerString("$$$$ Checking $$$$");
    cout << endl;       
    centerString("Account  Activites");
    cout << endl;       
    centerString("==================");
    cout << endl;       
    centerString("1) ----Deposit----");
    cout << endl;
    centerString("2) ----Withdraw---");
    cout << endl;
    centerString("3) ----Transfer---");
    cout << endl;
    centerString("4) ----Balance----");
    cout << endl;
    centerString("5) Personal  Check");
    cout << endl;
    centerString("6) ----Interest---");
    cout << endl;
    centerString("7) ---Statement---");
    cout << endl;
    centerString("8) -----Exit------");
    cout << endl;
    centerString("Enter selection: ");

    // Validate user input for menu choice
    while(!(cin >> choice) || (choice != 1 && choice != 2 && choice != 3 && choice != 4 && choice != 5 && choice != 6 && choice != 7 && choice != 8))
    {
        cout << "Error: Please re-enter a correct choice: ";
        cin.clear();
        fflush(stdin);
    }

    //Switch for user choices
    switch(choice)
    {
    case 1:
        {
            string userInput;
            double dollars;
            centerString("*** Deposit ***");
            cout << endl;
            centerString("Amount to deposit: ");
            cin >> userInput;
            dollars = validCurrency(userInput);             
        }
    case 2:
        {

        }
    case 3:
        {

        }
    case 4:
        {
            checkingObject.Balance();               
        }
    }
} while (choice != 8);
}

アカウント ヘッダー

#ifndef ACCOUNT_H
#define ACCOUNT_H

#include<string>
using namespace std;

class Account
{
private:


string nameString;
    string titleString;
    string SSNString;
    string IDString;
public:
    //Constructor
    Account();

    // Mutators
    void setName(string), setTitle(string), setSSN(string), setID(string);
    virtual void Deposit(double);
    virtual void Withdraw(double);
    virtual void Transfer(string, double);
    virtual void Balance();
    virtual void Check();
    virtual void Interest();

    // Accessors
    virtual void Statement() const;
};
#endif  

ヘッダーの確認

#ifndef CHECKING_H
#define CHECKING_H
#include"Account.h"

class Checking : public Account
{
private:
    double balance;
    double rate;

public:
    Checking(); // Default Constructor
    Checking(double, double);
    void Deposit(double);   
    void Balance();

};

#endif
4

4 に答える 4

3

いくつかの問題があります。まず、これは仮想メソッドをオーバーライドしていません。

void Balance(Checking &);

これは、親メソッドを非表示にする新しいメソッドを定義しています。派生仮想メソッドは同じシグネチャを持つ必要があります。次の呼び出し:

Checking::Balance(&checkingObject);

いくつかの点で奇妙ですが、次のようになります。

someInstanceOfChecking.Balance(checkingObject);

これ&checkingObjectは へのポインタになりますcheckingObject。メソッドが参照を取得すると、参照を取得しているオブジェクトのインスタンスを渡す以外に何もする必要がなく、舞台裏で作業を行います。

アップデート:

新しく投稿されたコードに基づいて、これは次の合理的な実装のようですChecking::Balance:

void Checking::Balance()
{
    std::cout << balance;
}

それは私には明らかではありませんAccount::Balanceが。また、私はあなたのより大きな問題を見ていると思います.あなたのグローバルは適切に定義されていません.これはあなたが望むものです:

Account accountObject;
Checking checkingObject;
Savings savingsObject;

コードに含まれているのは、関数の宣言です。たとえば、次のようになります。

Checking checkingObject();

checkingObjectオブジェクトを返すために呼び出される関数を宣言しCheckingます。

于 2013-05-18T01:27:57.657 に答える
2

もっと多くのコードを見なければ、完全に確信することは困難です。しかし、私はこれの代わりにそれを信じています:

Checking::Balance(&checkingObject);

あなたが欲しいのはこれです:

checkingObject.Balance();

そしてこれの代わりに:

void Balance(Checking &)

これ:

void Balance()
于 2013-05-18T01:27:44.467 に答える
1

checkingObjectOK、まず、あなたの呼び出しは(つまり、 a )へのポインタを取得していますChecking *。それはあなたが望むものではなく、代わりに , の代わりに渡すだけcheckingObjectです&checkingObject

次に、仮想関数を呼び出していません。仮想関数を適切にオーバーロードするには、子クラスの関数が親と同じシグネチャ (すべてのパラメーターと戻り値が同じである必要があります) を持っている必要があります。あなたがしていることは、同じ名前で異なる署名を持つ新しい関数を作成することです。クラス名を使用して呼び出すので、必要なものを取得できますが、Accountオブジェクトを取得Balance(checkingObject)してそれを呼び出そうとすると失敗します。

于 2013-05-18T01:28:15.330 に答える