开发者

Small question concerning redefining member functions

开发者 https://www.devze.com 2022-12-13 20:53 出处:网络
I\'m t开发者_如何学JAVArying to redefine two member functions from their parent\'s definition.I don\'t know if I have it right or not, but something in my code has errors attached and I can\'t find ou

I'm t开发者_如何学JAVArying to redefine two member functions from their parent's definition.

I don't know if I have it right or not, but something in my code has errors attached and I can't find out what.

some of the header:

class Account 
{
public:
   Account(double);
   void creditBalance(double);
   void debitBalance(double);
   double getBalance() const;
protected:
   double balance;      
};


class CheckingAccount : public Account
{
public:
   CheckingAccount(double, double);
   void feeCreditBalance(double);
   void feeDebitBalance(double);

private:
   double fee = 10;

};

relevant cpp file part:

void Account::creditBalance(double plus)
{
   if(plus > 0)
      balance += plus;
   else
      cout << "Cannot credit negative.";
}

void Account::debitBalance(double minus)
{
   if(minus <= balance)
      balance -= minus;
   else
      cout << "Debit amount exceeded account balance.";
}

void CheckingAccount::feeCreditBalance(double plus)
{
   if(plus > 0){
      balance += plus;
      balance -= fee;
   }
   else
      cout << "Cannot credit negative.";
}

void CheckingAccount::feeDebitBalance(double minus)
{
   if(minus <= balance){
      balance -= minus;
      balance -= fee;
   }
   else
      cout << "Debit amount exceeded account balance.";
}

UPDATE:

I added this:

class Account 
{
public:
   Account(double);
   virtual void creditBalance(double);
   virtual void debitBalance(double);
   double getBalance() const;
protected:
   double balance;      
};

Now I get error: virtual outside class declaration

I could use an example of how to properly initialize fee correctly.

EDIT 2:

I have tried changing the constructor line to this:

CheckingAccount::CheckingAccount(double initBal, double phi) :  Account(initBal), fee(phi)
{
   if(initBal < 0)
      initBal = 0;
   balance = initBal;
   cerr << "Initial balance was invalid.";

   if(phi < 0)
      phi = 0;
   fee = phi;
}

not working, I'm going to work around with changing syntax on the fee(phi) part. I don't know if anyone will respond to this.


You can not initialise member variables in place(double fee = 10) like that. You have to initialise then in the initiasation list in the derived class constructor. Also note that if you are using inheritance you should make base class destructor virtual.


If the intention is that for instances of CheckingAccount accounts the versions which use a fee is called, then you want to use virtual methods.

A virtual method is a method decalared (at least in the base class) as "virtual", and has the same name and signiture in any derived classes. When a virtual method is called, it will call the "most derived" version for the instance.

To do this just declare "void creditBalance(double);" and "void debitBalance(double);" virtual (ie "virtual void creditBalance(double);" and "virtual void debitBalance(double);". Then in CheckingAccount rename "feeCreditBalance" and "feeDebitBalance" to "creditBalance" and "debitBalance".

EDIT: Simple example.

Header

class Base
{
public:
    Base(int x);
    //declare virtual so that derived classes may overide it
    virtual void sayHello();
protected:
    int x;
};

class Derived : public Base
{
public:
    Derived(int x, int y);
    //overide Base::sayHello(). the virtual keyword here is optional.
    virtual void sayHello();
protected:
    int y;
};

Cpp

Base::Base(int x)
    :x(x)
{}
Derived::Devired(int x, int y)
    :Base(x), y(y)
{}
void Base::sayHello()
{
    std::cout << "Hello from Base!" << std::endl;
    std::cout << "X = " << x << std::endl;
}
void Derived::sayHello()
{
    std::cout << "Hello from Derived!" << std::endl;
    std::cout << "X = " << x << "  Y = " << y << std::endl;
}

int main()
{
    Base a(5);
    a.sayHello();//"Hello from Base!..."

    Derived b(10, -20);
    b.sayHello();//"Hello from Derived!..."

    Base *c = &b;//take pointer to b, reference would also do
    c->sayHello();//"Hello from Derived!..." because its a Derived instance, eventhough its a Base variable.
}

You can then derive from Derive again (class DerivedAgain : public Derived) and also overload the functions again.

You can also derive multiple subclasses from Base, which can each have their own overrides for the virtual methods, just like I did for the Derived class.

EDIT2: Added variables to example and how to use initialiser list to initialise the base class and member variables.


When you want to override a method in the parent class, you should give the method the same name. Don't call it feeCreditBalance if you want it to override creditBalance. Also, you need to use the "virtual" keyword in the definition of the parent class's method if you want a call to creditBalance to always use the one from the child class.


You need to learn overriding the member function ( using virtual keyword) . IF you want to change the base class member function implementation then you need to override those methods and provide different implementation in derived classes.

EDIT:

double fee = 10;

This may be the error which you are talking. Use member initializer list to initialize fee. You cannot initialize fee as in-class constant.


I think fee should be static const if it remains constant and does not vary for each object.

Declare in the class like this:

static const double fee;

Define outside class like this:

const double ClassName::fee = 10;

And if you want your implementation should not allow -Ve balance than something like this and also you should make use of virtual functions in inheritance which is better approach:

void CheckingAccount::feeCreditBalance(double plus)
{
    if(plus - fee > 0)
        balance += (plus - fee);
    else
        cout << "Cannot credit negative.";
}
0

精彩评论

暂无评论...
验证码 换一张
取 消