ahuttune@niksula.hut.fi (Ari Juhani Huttunen) (12/01/90)
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
randolph@ssd.kodak.com (Gary L. Randolph) (12/03/90)
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