Wednesday, 7 October 2009

Inheritance

You long lost aunt left you loads of cash, but when her solicitor called to give you her rubels, it turned out you'd only overridden the sterling deposit capability.

just found a website called the C++ FAQ LITE, and section 23, part 3 has an interesting take on how to solve the problem of overloaded overrides.

class Person
{
public:
virtual void Deposit( Sterling amount ) { PutUnderBed( ToCash( amount ) ); }
virtual void Deposit( Rubels amount ) { PutUnderBed( ToCash( amount ) ); }
virtual void Deposit( Euros amount ) { PutUnderBed( ToCash( amount ) ); }
}

class Me : public Person
{
public:
// this overrides the deposit mechanism in Person so that it pays straight into my bank account
virtual void Deposit( Sterling amount ) { PutInBank( amount ); }
}

In this code, the Sterling argumented version overrides all of the base class virtuals. When our auntie clips her clogs, she leaves us rubels, but we can't accept because we've not implemented banking our rubels.

Handled Differently:


class Person
{
public:
void Deposit( Sterling amount ) { DepositSterling( amount ) ); }
void Deposit( Rubels amount ) { DepositRubels( amount ) ); }
void Deposit( Euros amount ) { { DepositEuros( amount ) ); }

protected:
virtual void DepositSterling( Sterling amount ) { PutUnderBed( ToCash( amount ) ); }
virtual void DepositRubels( Rubels amount ) { PutUnderBed( ToCash( amount ) ); }
virtual void DepositEuros( Euros amount ) { PutUnderBed( ToCash( amount ) ); }
}

class Me : public Person
{
protected:
// this overrides the deposit mechanism in Person so that it pays straight into my bank account
virtual void DepositSterling( Sterling amount ) { PutInBank( amount ); }
}

Now, stirling goes into my bank account, but rubels still go under the bed, and I can be thankful of having a dead auntie.

This idea of allowing the base class to reinterpret functionality and leave defaults in place is a nice way of securing your code against accidental casts to the wrong type to make things fit where they can go (imagine ignoring the warning that it's converted an int to a float, and much later finding out that it's called the wrong function instead of doing what you thought it should).
Post a Comment