簡體   English   中英

C ++調用虛擬函數時遇到麻煩

[英]c++ trouble calling a virtual function

好的,對多態性和虛函數來說還很陌生,即使調用第一個函數也遇到問題。 我認為問題出在電話本身,因為這會返回錯誤;

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

我很確定,這意味着我將錯誤的東西傳遞給了函數。 我知道我不能只為虛擬函數傳遞類實例的名稱,它必須通過ref或作為指針。 我嘗試了兩種方法,並得到相同的錯誤。

我省略了復制並粘貼了整個內容,因為這是一個銀行項目,並且有大量(如果不相關)用於輸入驗證的內容。 父類是“帳戶”,“支票”是從其派生的子類。 “ checkingObject”是我嘗試調用的“ Checking”類實例的名稱。

主.cpp中的函數調用:

Checking::Balance(&checkingObject);

在Account.h中聲明(父類):

virtual void Balance();

在Checking.h(子類)中重新聲明:

void Balance(Checking &);

在Checking.cpp中定義(balance是該類的私有成員):

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

}

我必須缺少一些東西,但是我只是想將對象checkingObject傳遞給該函數。 我真的不理解錯誤消息的一部分“無法從'Checking(__cdecl *)(void)'轉換參數1”。 我對ClassName&的理解是,它將接受從該類派生的任何對象。

編輯:為了清晰起見,包括更多代碼。

在banking.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

有幾個問題,首先這不是覆蓋虛擬方法:

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對象。

沒有看到更多的代碼,很難完全確定。 但我相信,除了這個:

Checking::Balance(&checkingObject);

您想要的是:

checkingObject.Balance();

而不是這樣:

void Balance(Checking &)

這個:

void Balance()

好的,首先,您的調用使用了一個指向checkingObject的指針(即Checking * )。 那不是您想要的,而是只傳遞checkingObject ,而不是&checkingObject

其次,您沒有調用虛函數。 為了適當地重載虛擬函數,子類函數必須具有與父類相同的簽名(所有參數和返回值必須相同)。 您正在做的是創建一個具有相同名稱和不同簽名的新功能。 現在,由於使用類名調用了該類,因此您將獲得所需的類,但是如果要使用一個Account對象並嘗試在其上調用Balance(checkingObject) ,它將失敗。

這里有很多問題。 首先:

void Balance(Checking &);

不重寫virtual void Balance(); 您在Account聲明的方法。 方法簽名應該相同。 例如,在您的Checking類中,它應如下所示:

void Balance();

然后Checking.cpp應該顯示為:

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

那么main中的調用應如下所示:

Checking account;    // Creates the checking account object
account.Balance();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM