[comp.lang.c++] Calling Parent functions in Child??? - not always ..

rcp@moth.sw.mcc.com (Rob Pettengill) (05/15/91)

In article <1991May15.044458.21518@minyos.xx.rmit.oz.au> s892992@minyos.xx.rmit.oz.au (Bossman) writes:
;ACPS2924@Ryerson.Ca writes:
;
;>If one has the following situation :
;
;>class A { int isEqual{}; }
;
;>class B : public A { int isEqual{} }
;
;>B::isEqual()
;>{
;>    return (... && // here i want to call the parents isEqual
;>                   // how do i do it??
;>}
;
;   Inside the isEqual member function of B, a call to isEqual will result in
;a recursive call back to the same member funcion. To call A's version of
;isEqual, you need to use scope resolution. You can do this as follows:
; 
;B::isEqual()
;{
;    return (... && A:isEqual() );
;}
;
;Simple huh! In fact the call to B's isEqual() member function can be structured
;the same way (ie: B::isEqual() ), but it is implicit that you are calling B's
;member functions from within a member of B.
; 
;See ya,
;       Kendall Bennett.

This technique does not work for "mixin" style classes with multiple
inheritance.   A mixin class is designed to augment any of a number of
possible parent classes.  Mixins that add completely new functionality
will work in c++.  However mixins that seek to augment existing member
functions run into the following difficulty.

For an over simplified examaple -  one might want to write a
MetricWeightMixin that could be added to any class that returned an
English Weight.

class MetricWeightMixin : {
public:
  virtual float weight();
}

MetricWeightMixin::weight()
{
  return lbsToKilos( DontKnowWhatClassToPutHere::weight());
}

;rob

--
  Robert C. Pettengill,       MCC Software Technology Program
  P. O. Box 200195, Austin, Texas  78720,     +1 512 338-3533
  INTERNET:  rcp@mcc.com   UUCP:  ..!cs.utexas.edu!milano!rcp

-- 
  Robert C. Pettengill,       MCC Software Technology Program
  P. O. Box 200195, Austin, Texas  78720,     +1 512 338-3533
  INTERNET:  rcp@mcc.com   UUCP:  ..!cs.utexas.edu!milano!rcp

mittle@blinn.watson.ibm.com (Josh Mittleman) (05/17/91)

In article <3022@moth.sw.mcc.com>, rcp@moth.sw.mcc.com (Rob Pettengill) writes:

> > B::isEqual()
> > {
> >     return (... && A:isEqual() );
> > };


> This technique does not work for "mixin" style classes with multiple
> inheritance.   A mixin class is designed to augment any of a number of
> possible parent classes.  Mixins that add completely new functionality
> will work in c++.  However mixins that seek to augment existing member
> functions run into the following difficulty.
> 
> class MetricWeightMixin : {
> public:
>   virtual float weight();
> }
> 
> MetricWeightMixin::weight()
> {
>   return lbsToKilos( DontKnowWhatClassToPutHere::weight());
> }


True, the method first described won't work, but that's because you are
dealing with an entirely different situation.  The original post wanted
to know how to explicitly access a base class member: Your
MetricWeightMixin has no base class.  If I understand correctly, you are
doing something like this:

	MetricWeightMixin    AnyClass which defines float weight, and returns
                     \       weights in pounds
                      \         /
                  Subclass which is identical to AnyClass, but
                  its weight() returns kilograms.

To be frank, I can't see any way to make this work.  The problem is that
you aren't abstracting the property of weightedness properly.  I would
define an abstract class WeightedObject, two subclasses
MetricWeightedObject and EnglishWeightedObject, and then derive more
useful classes from one or the other of these:

class WeightedObject {
protected:
  virtual float pounds() = 0; // returns weight in pounds.  This is
                              // used as an internal function,
			      // to provide a standard "base" weight.
  virtual float kilos() { return lbsToKilos(pounds()); }
  float lbsToKilos(const float);
  float kilosToLbs(const float);

    // Note that in this case, I've assumed that a derived class will
    // first compute its weight in pounds, and then will be able to
    // convert that to kilos.  Obviously, any particular derived class
    // could re-implement these functions to do the opposite.

public:
  virtual float weight() = 0;
};

class MetricWeightedObject {
public:
  float weight() { return kilos(); }
};

class EnglishWeightedObject {
public:
  float weight() { return pounds(); }
};


===========================================================================
Josh Mittleman (mittle@watson.ibm.com or joshua@paul.rutgers.edu)
J2-C28 T.J. Watson Research Center, PO Box 704, Yorktown Heights, NY  10598