[comp.lang.c++] Calling Parent functions in Child

rae@alias.com (Reid Ellis) (05/24/91)

[ My apologies if this is seen twice -- I had some problems with our
  news server recently ]

Bossman <s892992@minyos.xx.rmit.oz.au> writes:
|To call A's version of isEqual, you need to use scope resolution. You
|can do this as follows:
|
|B::isEqual()
|{
|    return (... && A::isEqual() );
|}

Rob Pettengill <rcp@moth.sw.mcc.com> writes:
|This technique does not work for "mixin" style classes with multiple
|inheritance. [...] 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());
|}

The problem is that you are going about solving this problem the wrong
way.  What you would want in this situation is to build classes
representing the units involved and include copy constructors as
appropriate. e.g.:

	class lbs;	// imperial weight [pounds]
	class kg;	// metric weight [kilograms]

	// the following line is illegal, but I don't want to write
	// a whole class just for this example -- you get the idea.

	extern lbs X::weight();		// X only knows imperial measure

	X x;
	kg metricWeight = x.weight();	// calls kg::kg(const lbs &)

No mixin required.  As an alternative, you could instead provide
conversion operators for you classes to cast themselves to the
appropriate type.  For instance, instead of the constructor

	kg::kg(const lbs &);

you could have the operator

	lbs::operator kg();

In this way, *you* can choose who knows about whom -- does kg know
about lbs or does lbs know about kg?  If the relationship is one-way,
as would be the case for a distributed class library that you wouldn't
want to modify, then you can have both methods.  If you were writing
the kg class, for instance, you could have both of:

	kg::kg(const lbs &);	// convert pounds to kilos
	kg::operator lbs();	// convert kilos to pounds
	
						Reid

--
Reid Ellis
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]

Reid.Ellis@sunbrk.FidoNet.Org (Reid Ellis) (05/24/91)

[ My apologies if this is seen twice -- I had some problems with our
  news server recently ]

Bossman <s892992@minyos.xx.rmit.oz.au> writes:
|To call A's version of isEqual, you need to use scope resolution. You
|can do this as follows:
|
|B::isEqual()
|{
|    return (... && A::isEqual() );
|}

Rob Pettengill <rcp@moth.sw.mcc.com> writes:
|This technique does not work for "mixin" style classes with multiple
|inheritance. [...] 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());
|}

The problem is that you are going about solving this problem the wrong
way.  What you would want in this situation is to build classes
representing the units involved and include copy constructors as
appropriate. e.g.:

	class lbs;	// imperial weight [pounds]
	class kg;	// metric weight [kilograms]

	// the following line is illegal, but I don't want to write
	// a whole class just for this example -- you get the idea.

	extern lbs X::weight();		// X only knows imperial measure

	X x;
	kg metricWeight = x.weight();	// calls kg::kg(const lbs &)

No mixin required.  As an alternative, you could instead provide
conversion operators for you classes to cast themselves to the
appropriate type.  For instance, instead of the constructor

	kg::kg(const lbs &);

you could have the operator

	lbs::operator kg();

In this way, *you* can choose who knows about whom -- does kg know
about lbs or does lbs know about kg?  If the relationship is one-way,
as would be the case for a distributed class library that you wouldn't
want to modify, then you can have both methods.  If you were writing
the kg class, for instance, you could have both of:

	kg::kg(const lbs &);	// convert pounds to kilos
	kg::operator lbs();	// convert kilos to pounds
	
						Reid

--
Reid Ellis
rae@utcs.toronto.edu        ||               rae@alias.com
CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]

 * Origin: Seaeast - Fidonet<->Usenet Gateway - sunbrk (1:343/15.0)

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

In article <1991May24.052212.27585@alias.com> rae@alias.com (Reid Ellis) writes:
;[ My apologies if this is seen twice -- I had some problems with our
;  news server recently ]
;
;Bossman <s892992@minyos.xx.rmit.oz.au> writes:
;|To call A's version of isEqual, you need to use scope resolution. You
;|can do this as follows:
;|
;|B::isEqual()
;|{
;|    return (... && A::isEqual() );
;|}
;
;Rob Pettengill <rcp@moth.sw.mcc.com> writes:
;|This technique does not work for "mixin" style classes with multiple
;|inheritance. [...] mixins that seek to augment existing member
;|functions run into the following difficulty.
;|
;|For an over simplified example -  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());
;|}
;
;The problem is that you are going about solving this problem the wrong
;way.  What you would want in this situation is to build classes
;representing the units involved and include copy constructors as
;appropriate. e.g.:
;....
;
;--
;Reid Ellis
;rae@utcs.toronto.edu        ||               rae@alias.com
;CDA0610@applelink.apple.com ||      +1 416 362 9181 [work]

The point of my trivial example was NOT that there was no way to solve
this problem in C++.  Of course C++ offers a number of ways to solve
any given problem - especially when you have the freedom to redesign
the class library for each problem.  However, other object oriented
languages have over many years developed techniques such as mixins
that are powerful means of modifying and extending existing libraries
of classes.  Unfortunately because of limitations like this one, C++
class libraries may prove much closer to standard C libraries in their
reusability and extensibility properties than to the Smalltalk and
Lisp class libraries.  

;rob

P.S.

C++ is a much more complicated language than C (more ways to make
errors, more time to compile, harder to debug).  My experience so far
has been that C++ offers very little in the way of object oriented
expressiveness to justify its cost/complexity.  For the little that it
does for me, I would just as soon manage my own structs and function
tables. 


-- 
  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