1

I am trying to call the function calculateInterest() in this class

// account.h -- handles banking accounts
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include <string>
using std::string;

class Account
{
private:
    double balance;
public:
    Account(double b = 0.0);
    double getBalance() {return balance;}
    void credit(double c);
    void debit(double d); 
};

class SavingsAccount : public Account
{
private:
    double rate;
public:
    SavingsAccount(double r = 0.0);
    double calculateInterest();
};



class CheckingAccount : public Account
{
private:
    double fee;
public:
    CheckingAccount(double f = 0.0);
    void credit(double m);
    void debit(double m);
};


#endif

So far I could do Account joe(100); and then use the functions inside of the Account class so I obviously am not inheriting it right.

8
  • what is your question exactly? Commented Apr 17, 2013 at 23:36
  • How would I make it so I can use say the function joe.calculateInterest() because with how it is now I can only use functions in the base class Commented Apr 17, 2013 at 23:39
  • you would like to ask Account to use functions inside its derived class? Commented Apr 17, 2013 at 23:40
  • 1
    Have you tried reading a C++ book? SAMS Teach Yourself C++ in 21 Days (5th edition) is the best for beginners. Commented Apr 17, 2013 at 23:50
  • Planning on learning C++ in 21 days is going to leave you with just enough knowledge to shoot your foot off at the knee, and make you a nightmare professionally for anyone you have to work with. It takes a lot more than 21 days to be a decent, let alone proficient C++ developer. Commented Apr 18, 2013 at 0:40

3 Answers 3

1
class Account
{
private:
    double balance;
public:
    Account(double b = 0.0);
    double getBalance() {return balance;}
    void credit(double c);
    void debit(double d);

    // add this!
    virtual double calculateInterest() = 0;
};

You will need to implement calculateInterest in all derived classes

Sign up to request clarification or add additional context in comments.

Comments

1

You currently only have the base class instance. You can not use that to call methods of the derived class.

If you have an instance of the derived class, you may use that to call methods of the derived class.

SavingsAccount joe(100);
joe.calculateInterest();

since this is the derived class, you can also call credit() or debit().

unrelated: You should define credit and debit as virtual functions, if you plan on using polymorphism.

Comments

1

1) None of your functions are virtual, so none can be properly overridden by derived classes.

2) Account joe(100) creates an instance of the class Account, not an instance of the class SavingsAccount. If you want to call calculateInterest on joe, joe needs to be a SavingsAccount. Account, SavingsAccount, and CheckingAccount are all still their own unique classes. SavingsAccount and CheckingAccount inherit Account's data and interface, but Account does not inherit theirs.

3) If you want to instantiate joe as a SavingsAccount but store and treat it like an Account, then you need to make a pointer to Account and upcast it, but you won't have access to a SavingsAccount function if you're treating it like an Account. In that case, you would need to move calculateInterest into Account (and make it pure virtual if desired), then override it in SavingsAccount.

class Account
{
  // Add this to your Account class
  virtual double calculateInterest() = 0;
};

class SavingsAccount : public Account
{
  // Add this to your SavingsAccount class
  double calculateInterest() override;
};

Then to create joe as a SavingsAccount but treat it like an Account:

SavingsAccount joe(100);
Account* pJoe = &joe;
double val = joe->calculateInterest();  // calculateInterest is available from Account, but because it's virtual, it calls the one from SavingsAccount.

If you don't want to force all derived classes to implement this function, then you really need to rethink your whole design here. In any case, one cheap way to get around it would be to make it non-pure (remove the = 0 from the declaration, but keep the virtual) and provide a default implementation that returns some default value.

Here is an example of that:

class Account
{
  // Add this
  virtual double calculateInterest() { return 0.0; }
};

class SavingsAccount : public Account
{
  // Add this
  double calculateInterest() override;  // and use your existing implementation
};

Now if you call calculateInterest on a SavingsAccount, it'll return the SavingsAccount's return value. If you call calculateInterest on a CheckingAccount, it'll return the default implementation provided by Account, which is 0.0. If you call calculateInterest on an Account* pointer to a SavingsAccount instance, it'll return the SavingsAccount's return value, because it is virtual.

3 Comments

Now I'm getting this error 1>error C2259: 'Account' : cannot instantiate abstract class 1>due to following members: 1>'double Account::calculateInterest(void)' : is abstract 1>see declaration of 'Account::calculateInterest'
Don't instantiate an Account, create a SavingsAccount or CheckingAccount. I think you're missing something essential here.
The presence of a pure virtual function makes Account an abstract class. That means it cannot be instantiated, only inherited from. Any function that is marked =0 in Account MUST be overridden by child classes. As I mentioned in the post, if you don't want all classes to have the function, then make it non-pure (remove the =0) and provide a DEFAULT implementation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.