user2391882
user2391882

Reputation: 3

c++ trouble calling a virtual function

OK, so new to polymorphism and virtual functions, and I'm having issues even calling my first function. I believe the issue is in the call itself, because this returns the error;

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

Which I'm pretty sure means I'm passing the wrong thing to the function. I know that I can not just pass the name of the instance of a class for virtual functions, that it must be by ref or as a pointer. I have tried both methods and get the same error.

I am omitting copy and pasting the entire thing, as it is a banking project and there is a ton if unrelated stuff for input validation. The parent class is 'Account' and 'Checking' is the child derived from it. 'checkingObject' is the name of the instance of the class 'Checking' that I am trying to call on.

Function call in main .cpp:

Checking::Balance(&checkingObject);

Declared in Account.h (Parent class):

virtual void Balance();

Re-Declared in Checking.h (child class):

void Balance(Checking &);

Defined in Checking.cpp (balance is a private member of the class):

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

}

I must be missing something, but I'm just trying to pass the the object checkingObject as a reference to the function. I really don't understand the part of the error message "cannot convert parameter 1 from 'Checking (__cdecl *)(void)'". My understanding of ClassName & is that it would take any object derived from the class.

EDIT: Including more code for clarity.

In banking.cpp (Main file)

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);
}

Account header

#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  

Checking Header

#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

Upvotes: 0

Views: 270

Answers (4)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158599

There are few issues, first this is not overriding the virtual method:

void Balance(Checking &);

This is defining a new method that will hide the parent method, derived virtual methods need to have the same signature. Next this call:

Checking::Balance(&checkingObject);

is odd in a few ways, it should be:

someInstanceOfChecking.Balance(checkingObject);

This &checkingObject will be a pointer to a checkingObject. When a method takes a reference it does the work behind the scenes you do not have to do anything but pass an instance of the object you are taking a reference to.

Update:

Based on your newly posted code this seems like a reasonable implementation of Checking::Balance:

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

Although it is not clear to me what Account::Balance does. Also, I think I see your larger issue, your globals are not defined properly, this is what you want:

Account accountObject;
Checking checkingObject;
Savings savingsObject;

What you have in your code is declaration of functions, for example, this:

Checking checkingObject();

declares a function called checkingObject that returns a Checking object.

Upvotes: 3

Steve
Steve

Reputation: 7271

There are a number of issues here. Firstly:

void Balance(Checking &);

does not override the virtual void Balance(); method you have declared in Account. The method signature should be the same. E.g. in your Checking class, it should look like:

void Balance();

The Checking.cpp then should read:

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

The call in main should then look like:

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

Upvotes: 1

Michael Kohne
Michael Kohne

Reputation: 12044

OK, first, your call is taking a pointer to checkingObject (that is, a Checking *). That's not what you want, instead just pass checkingObject, instead of &checkingObject.

Second, you aren't calling a virtual function. To properly overload a virtual function, the child class function must have the same signature (all parameters and return values must be the same) as in the parent. What you are doing is creating a new function with the same name and a different signature. Now since you call it using the class name, you'll get the one you want, but if you were to take an Account object and try to call Balance(checkingObject) on it, it would fail.

Upvotes: 1

ruakh
ruakh

Reputation: 183554

Without seeing more code, it's hard to be completely certain; but I believe that instead of this:

Checking::Balance(&checkingObject);

what you want is this:

checkingObject.Balance();

and instead of this:

void Balance(Checking &)

this:

void Balance()

Upvotes: 2

Related Questions