Topic: Multiple inheritance and pointers to base class.


Author: ahuttune@niksula.hut.fi (Ari Juhani Huttunen)
Date: 30 Nov 90 22:03:46 GMT
Raw View
How do you use multiple inheritance and pointers to a base class object at
the same time? Suppose you have many different classes from which you wish
to construct objects using multiple inheritance and you also wish to access
these objects through a pointer to their common base class. Example:

Animal - AnimalWithWingsAndTeeth
       - AnimalWithWingsAndFeet
       - AnimalWithFeetAndScales
          ...

You access these through a pointer to Animal. You have implemented classes
named Wings, Teeth, Feet, Scales that implement functions fly, bite, run,
protect. (And NoWings, NoTeeth, NoFeet, NoScales that do not.)

The easy way to proceed would be:

class Animal {
public:
  virtual fly() = 0;
  virtual bite() = 0;
  virtual run() = 0;
  virtual protect() = 0;
};

class AnimalWithWingsAndTeeth :
  public Wings, public Teeth, public NoFeet, NoScales
{};

class AnimalWithWingsAndFeet :
  public Wings, public NoTeeth, public Feet, NoScales
{};

class AnimalWithFeetAndScales :
  public NoWings, public NoTeeth, public Feet, Scales
{};

Instead you are forced to write:

class AnimalWithWingsAndTeeth :
  public Wings, public Teeth, public NoFeet, NoScales {
public:
  fly() { Wings::fly(); }
  bite() { Teeth::bite(); }
  run() { NoFeet::run(); }
  protect() { NoScales::protect(); }
};

class AnimalWithWingsAndFeet :
  public Wings, public NoTeeth, public Feet, NoScales {
public:
  fly() { Wings::fly(); }
  bite() { NoTeeth::bite(); }
  run() { Feet::run(); }
  protect() { NoScales::protect(); }
};

class AnimalWithFeetAndScales :
  public NoWings, public NoTeeth, public Feet, Scales {
public:
  fly() { NoWings::fly(); }
  bite() { NoTeeth::bite(); }
  run() { Feet::run(); }
  protect() { Scales::protect(); }
};

My question: Is it really necessary to force a programmer to write this much
(and more since this is only a small example) unnecessary code? Why can't
the multiple inheritance of a non-virtual function, say Wings::fly(),
re-define a virtual function Animal::fly() ? Am I missing something?
--
  ___  ___  ___  ___  ___  ___  ___  ___  ___
__I I__I I__I I__I I__I I__I I__I I__I I__I I  Bird of Night: 2 cl Kahlua
 Ari Huttunen    (ahuttune@niksula.hut.fi)  I                 2 cl Jameson
____________________________________________I                 add ice cubes




Author: randolph@ssd.kodak.com (Gary L. Randolph)
Date: 3 Dec 90 14:11:48 GMT
Raw View
In article <AHUTTUNE.90Nov30230346@wolverine.hut.fi> ahuttune@niksula.hut.fi (Ari Juhani Huttunen) writes:
>
>How do you use multiple inheritance and pointers to a base class object at
>the same time? Suppose you have many different classes from which you wish
>to construct objects using multiple inheritance and you also wish to access
>these objects through a pointer to their common base class. Example:
>
>Animal - AnimalWithWingsAndTeeth
>       - AnimalWithWingsAndFeet
>       - AnimalWithFeetAndScales
>          ...
>
>You access these through a pointer to Animal. You have implemented classes
>named Wings, Teeth, Feet, Scales that implement functions fly, bite, run,
>protect. (And NoWings, NoTeeth, NoFeet, NoScales that do not.)
                                                  ^^^^^^^^^^^
              Not clear what you mean here.  The functions must be defined or the
   call to the member function is an error.  You may have null bodied functions
   here if you like, but you cannot keep the functions pure virtual and call them.

>
>The easy way to proceed would be:
>
>class Animal {
>public:
>  virtual fly() = 0;
>  virtual bite() = 0;
>  virtual run() = 0;
>  virtual protect() = 0;
>};
>
>class AnimalWithWingsAndTeeth :
>  public Wings, public Teeth, public NoFeet, NoScales
>{};
>
>class AnimalWithWingsAndFeet :
>  public Wings, public NoTeeth, public Feet, NoScales
>{};
>
>class AnimalWithFeetAndScales :
>  public NoWings, public NoTeeth, public Feet, Scales
>{};
>
>Instead you are forced to write:
>
>class AnimalWithWingsAndTeeth :
>  public Wings, public Teeth, public NoFeet, NoScales {
>public:
>  fly() { Wings::fly(); }
>  bite() { Teeth::bite(); }
>  run() { NoFeet::run(); }
>  protect() { NoScales::protect(); }
>};
>
  and so forth...
>
>My question: Is it really necessary to force a programmer to write this much
>(and more since this is only a small example) unnecessary code? Why can't
>the multiple inheritance of a non-virtual function, say Wings::fly(),
>re-define a virtual function Animal::fly() ? Am I missing something?

Yes, you are missing quite a bit:-)

First, smile, because all you are asking for is simple to implement.

What you are trying for, is:

                        Animal
                         /...\
                        / ... \
                     Teeth... Feet
                       \  ... /
                        \ .../
                         \  /
                  AnimalWithTeethAndFeet

Where the elipsis are fill for NoTeeth, Wings, etc...


Since only one instance of Animal is necessary for each instance, the derived
classes will agree to share one Animal.  In C++ terms, Teeth, Feet, etc will
virtually derive from Animal.

In your code, you privately derived NoScales and Scales since you left out the
public reserved word.  That was probably just a (major) oversight.

The following will do precisely what you want, and notice that NOT ONCE, is the
scope resolution operator used.

I am using 2.0 and therefore cannot inherit pure virtual functions, so in the
example below, I have null bodied functions. In 2.1 inheriting pure virtual
functions as remaining pure virtuals should be allowed (but you still don't call
them!)
------------------------------------------------------------------------------


#include <iostream.h>

class Animal{
 public:
  virtual void fly(){};
  virtual void bite(){};
  virtual void run(){};
  virtual void protect(){};
};

class Teeth:virtual public Animal{
 public:
  virtual void bite(){
   cout<<"\nMunching animal, chomp, chomp.";
  }
};

class NoTeeth:virtual public Animal{
 public:
  virtual void bite(){
   cout<<"\nLook out, I'll GUM you to death!";
  }
};


class NoFeet:virtual public Animal{
 public:
  void run(){
   cout<<"\nDon't ask me to run, I gots no feet!";
  }
};

class NoScales:virtual public Animal{
 public:
  void protect(){
   cout<<"\nI guess my lack of scales leaves me vulnerable.";
  }
};

class Wings:virtual public Animal{
 public:
  void fly(){"\nI put out my hand, and touch the face of God.";}
};

class AnimalWithWingsAndTeeth:
 public Wings,public Teeth, public NoFeet, public NoScales{};

main(){
AnimalWithWingsAndTeeth *flyingMunchy =new AnimalWithWingsAndTeeth;
Animal *ap = flyingMunchy;
ap->fly();
ap->bite();
ap->run();
ap->protect();
}
--------------------------------------------------------------------------
The output:

Munching animal, chomp, chomp.
Don't ask me to run, I gots no feet!
I guess my lack of scales leaves me vulnerable.


Gary




Author: jamiller@hpcupt1.cup.hp.com (Jim Miller)
Date: 4 Dec 90 22:44:47 GMT
Raw View
>Ari Juhani Huttunen
>
>How do you use multiple inheritance and pointers to a base class object at
>the same time? Suppose you have many different classes from which you wish
>to construct objects using multiple inheritance and you also wish to access
>these objects through a pointer to their common base class. Example:
>
>Animal - AnimalWithWingsAndTeeth
>       - AnimalWithWingsAndFeet
>       - AnimalWithFeetAndScales
>          ...
>
>You access these through a pointer to Animal. You have implemented classes
>named Wings, Teeth, Feet, Scales that implement functions fly, bite, run,
>protect. (And NoWings, NoTeeth, NoFeet, NoScales that do not.)
>
>The easy way to proceed would be:
>
>class Animal {
>public:
>  virtual fly() = 0;
>  virtual bite() = 0;
>  virtual run() = 0;
>  virtual protect() = 0;
>};
>
>class AnimalWithWingsAndTeeth :
>  public Wings, public Teeth, public NoFeet, NoScales
>{};
>
. . .

Maybe I'm missing your point, but the base class should not contain
all the things that the derived classes need.  The way you are using
Animal, a base class "Object" would need to have all the fields and
methods that any program would ever need (say, such a class should
be part of the C++ language definition, and so all that coders would
need to do is decide what not to use ... :-).

An AnimalWithWingsAndTeeth should inherit Animal and add Wings and Teeth,
not get rid of run.

Please re-post with a good example of the use of what you are talking
about, your example seems an example of bad OO design, not of a
difficulty in a language.

This was not ment as a flame.


   jim miller
   jamiller@hpmpeb7.cup.hp.com
   (a.k.a James A. Miller; Jim the JAM; stupid; @!?$$!; ... )
   Anything I say will be used against me ...
   But my company doesn't know or approve or condone anything of mine here.