Thread: conditional inheritance?

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    58

    conditional inheritance?

    I was writing a tutorial for inheritance and it made me question something that may be interesting. Why is it that an object cannot determine which base object it inherits from based on the constructor?
    For example:



    Imagine that some unknown Alien species invaded earth. One half of the species was a reptillian humanoid breed, while the other looked more like monkeys.


    Now consider these definitions for animal, reptile, and mammal:

    Animal.h:
    Code:
    #ifndef _ANIMAL_
    #define _ANIMAL_
    
    //typedef char* string;
    
    typedef const char Color;
    typedef const char Gender;
    typedef const char Texture;
    
    class Animal
    {
    public:
    	Animal(void) {}
    	~Animal(void);	
    };
    struct Colors
    {
    	static Color
    		Red = 0,
    		Blue = 1,
    		Green = 2,
    		Cyan = 3,
    		Magenta = 4,
    		Yellow = 5,
    		Black = 6,
    		White = 7,
    		Brown = 8,
    		Orange = 9,
    		Purple = 10;
    };
    
    struct Textures
    {
    	static Texture
    		Smooth = 0,
    		Rough = 1,
    		Ridged = 2;
    };
    
    struct Skin
    {
    public:
    	Skin(void) : _color(Colors::Black), _texture(Textures::Smooth) {}
    	Skin(Color color, Texture texture) : _color(color), _texture(texture) {}
    	~Skin(void) {}
    private:
    	Color _color;
    	Texture _texture;
    };
    
    struct Appendage
    {
    public:
    	Appendage(void);
    	~Appendage(void);
    };
    
    struct Offspring
    {
    public:
    	Offspring(void);
    	~Offspring(void);
    };
    
    
    
    
    struct Genders
    {
    	static Gender
    		Male = 0,
    		Female = 1,
    		Asexual = 2,
    		Unisex = 3;
    };
    
    
    #endif

    Mammal.h:
    Code:
    #ifndef _MAMMAL_
    #define _MAMMAL_
    #include "animal.h"
    struct Hair : public Skin
    {
    public:
    	Hair(void) {}
    	Hair(Color color, Texture texture) : Skin(color, texture) {}
    	~Hair(void) {}
    };
    
    class Mammal : public Animal
    {
    public:
    	Mammal(void) {}
    	Mammal(Hair hair) : Animal(), _hair(hair) {}
    	~Mammal(void);
    rivate:
    	Hair _hair;
    };
    
    struct Baby : public Offspring
    {
    public:
    	Baby(void);
    	~Baby(void);
    };
    #endif

    Reptile.h:
    Code:
    #ifndef _REPTILE_
    #define _REPTILE_
    #include "animal.h"
    struct Scales : public Skin
    {
    public:
    	Scales(void) {}
    	Scales(Color color, Texture texture) : Skin(color, texture) {}
    	~Scales(void) {}
    };
    
    
    
    class Reptile : public Animal
    {
    public:
    	Reptile(void) {}
    	Reptile(/*string Name,*/ Scales scales) : Animal(/*Name*/), _scales(scales) {}
    	~Reptile(void);
    private:
    	Scales _scales;
    };
    
    #endif

    So...with this in mind, we would now define the aliens:
    Alien.h:
    Code:
    #ifndef _ALIEN_
    #define _ALIEN_
    #include "reptile.h"
    #include "mammal.h"
    class ALIEN: public Mammal, public Reptile
    {
    public:
    	ALIEN(Scales scales) : Reptile(scales) {}
    	ALIEN(Hair hair) : Mammal(hair) {}
    	~ALIEN(void) {}
    };
    #endif

    Humans would identify the monkey aliens as mammals and the reptile ones as reptiles even though they are from the same race. (Lets also pretend they don't produce offspring in the conventional methods so you can't argue that they really are.)

    Here is a human:
    Code:
    class Human : public Mammal
    {
    public:
        Human(Hair hair, Texture texture) : Mammal(hair, texture) {}
        ~Human(void);
        string Identify(Animal animal); //This would give the class name as a string to identify the animal (Since even aliens would inherit from animal, they could be identified)
    };
    Now pretend that the alien mothership has a forcefield that doesn't allow any animals without the aliens' DNA to enter.
    In our ship, we "pickup" aliens with a function similar to:
    Code:
    void PickUpAliens(Alien *alien)
    {
        CrewList.Add(alien);
    }
    This makes it so that ONLY aliens can be on the ship.





    Now the situation here is as follows:
    -Humans and Aliens are both Animals
    -Humans are Mammals
    -Aliens can be Mammals or Reptiles (according to humans)
    -The Mothership will not allow for Humans or any other animals to come on board, other than aliens.
    -The mothership puts Reptile Aliens to hard labor, and the mammal aliens to the command center.

    So, in this situation (though it can be done many different ways), it would seem logical to have this "conditional inheritance" to quicken things up, even though it can be accomplished in different ways. (Just like how the strings quicken a lot in C#)

    Now...assuming that there is an actual occasion where you need to inherit from either one class or another, as this example hopefully illustrates, what would be the downside to a language that allows for inheritance like that? Would it even be possible?
    Keep in mind that I'm talking about conditional inheritance - meaning that aliens would determine the base properties from its constructor, and NOT from its declaration/definition.

    Feel free to point out how stupid the idea is, if it is. Just please be sure to give a detailed description of why it would be.
    Last edited by arcaine01; 09-04-2009 at 01:58 PM.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    You seem to have the inheritance concept backwards. "creature" is the general thing, "reptile" and "mammal" are more specific. Thus, mammal and reptile should both inherit from creature, not the other way around.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I'm guessing the downsides would be something like "it would be impossible to tell, given a random creature object, whether .some_member is even in the object." That seems like a lot of overhead -- it wouldn't be so bad if (for your example) you were looking at say "cut_hair" -- if it didn't get derived from a mammal, just let it be. But if your function needs to do something different for a reptile vs. a mammal vs. a bird vs. a fish vs........ ugh.

    I'm also trying to think of a decent use case. The example you give is pretty much backwards -- a reptile is-a creature and a mammal is-a creature, so creature should be your base and reptile and mammal your derived classes. All the examples I'm coming up with more or less fall under the "user shouldn't care about implementation" guideline -- i.e., maybe your queue is based on an array, or maybe it's based on a vector, or maybe something else, but I as a user shouldn't know or care anyway.

  4. #4
    3735928559
    Join Date
    Mar 2008
    Location
    RTP
    Posts
    838
    you can do something similar with template inheritance.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    58
    I'm very sorry if my previous explanation was not sufficient. I wanted to avoid typing a long example, but I guess it cannot be avoided.

    I changed my first post to extend upon my previous explanation...hopefully this is satisfactory.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Inherit ReptileAlien from BaseAlien and Reptile; MammalAlien from BaseAlien and Mammal?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    58
    Take into consideration that the mothership only picks up aliens.
    In your "answer", neither ReptileAlien or MammalAlien inherit from Alien, so the mothership ignores both of them, and leaves its crew behind....


    Also, please keep in mind that I am well aware of different ways to solve this problem. My question is simply "Why is conditional inheritance not a part of the C languages, and is it even plausible?"


    Like I stated above...it would simplify these types of situations immensely.
    Last edited by arcaine01; 09-04-2009 at 02:24 PM. Reason: needed to elaborate on my bolded question

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    In your "answer", neither ReptileAlien or MammalAlien inherit from Alien, so the mothership ignores both of them, and leaves its crew behind....
    Both are inherited from BaseAlien (which you might just call Alien). Also they are different types, so you can further be separated between command bridge and hard work. Since otherwise they are exactly the same (otherwise your idea would lead to great difficulties, implementing different behaviors in the same class), so all the implementation besides the constructors are in the base Alien.

    As you describe it, a) the need doesn't seem to be very convincing (it's just bad sci-fi ), b) it looks a bit like it would end in a bizarre mixture of dynamic and static typing.
    Last edited by anon; 09-04-2009 at 02:59 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by arcaine01 View Post
    Take into consideration that the mothership only picks up aliens.
    In your "answer", neither ReptileAlien or MammalAlien inherit from Alien, so the mothership ignores both of them, and leaves its crew behind....


    Also, please keep in mind that I am well aware of different ways to solve this problem. My question is simply "Why is conditional inheritance not a part of the C languages, and is it even plausible?"


    Like I stated above...it would simplify these types of situations immensely.
    If you use anon's approach, then whenever you need an Alien, both a MammalAlien and a ReptileAlien qualify; if you need a mammal-looking creature, then both a MammalAlien and a Mammal qualify. How is that hard -- in fact, how is that different from what you want or claim that you "have" with your scheme?

  10. #10
    Registered User
    Join Date
    Apr 2008
    Posts
    58
    This is essentially what I'm proposing:
    Code:
    class BaseAlien
    {
    public:
        BaseAlien(void);
    };
    class Reptile : public Animal
    {
    public:
        Reptile(void);
    }
    class Mammal : public Animal
    {
    public:
        Mammal(void);
    };
    class ReptileAlien : public BaseAlien, public Reptile
    {
    public:
        ReptileAlien(void);
    };
    class MammalAlien : public BaseAlien, public Mammal
    {
    public:
        MammalAlien(void);
    };


    This is the solution you just suggested, and it is the solution I mentioned above; The only difference between the two, is that in anon's solution (essentially what I wrote in this post) requires the programmer to write it, and a conditional inheritance would make the compiler write it out and avoid any errors with multiple inheritance.


    Though the need may not seem very high, I can list off many other language features that may seem fairly useless that are in common practice...such as the abstract keyword in C# (It looks like its just declaring a protected constructor, and signaling for the compiler to optimize it.)


    Even if the end result could be a little confusing, why wouldn't it be a good idea? Could you really not see a use for it? Is there something that I'm missing that makes the idea impossible? Please share any information you people have against this idea before I try to go out and write my own language and compiler that implements this :P
    Last edited by arcaine01; 09-04-2009 at 03:14 PM.

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So essentially you're taking two types and giving them the same name, thereby making it more difficult to tell them apart. To be honest, no I cannot see a use for that.

  12. #12
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by arcaine01 View Post
    My question is simply "Why is conditional inheritance not a part of the C languages, and is it even plausible?"
    You'll find it is not part of any object-oriented language: conditional inheritence (in the sense than an object decides what it inherits from) does not make sense from an object-oriented design perspective.

    The types of concepts you're seeking would normally be represented as containment: i.e. an object contains 0 or more components object depending on conditions.

    Inheritence can be represented as a restricted form of containment: each base is contained the exact number of times it is inherited. The reverse is not true - there are some containment relationships that cannot be represented using inheritence.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  13. #13
    Registered User
    Join Date
    Apr 2008
    Posts
    58
    Nope, because then you can make something like this:
    Code:
    class Alien
    {
    public:
        Alien(void);
        Alien(Scales scales) : Reptile(scales);
        Alien(Hair hair) : Mammal(hair);
    };
    class WorkerAlien : Alien
    {
    public:
        WorkerAlien(void);
        void DoWork(void);
    };
    class BureaucratAlien : Alien
    {
        BureaucratAlein(void);
        void StealWork(void);
    };

    ...and this way you could avoid multiple inheritance and all its glorious problems, by extending the branch of inheritance I called Alien. Otherwise, you would have to continue making new classes for each new derived alien class - exponentially increasing the amount of classes you have to make.

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by arcaine01 View Post
    Nope, because then you can make something like this:
    Code:
    class Alien
    {
    public:
        Alien(void);
        Alien(Scales scales) : Reptile(scales);
        Alien(Hair hair) : Mammal(hair);
    };
    class WorkerAlien : Alien
    {
    public:
        WorkerAlien(void);
        void DoWork(void);
    };
    class BureaucratAlien : Alien
    {
        BureaucratAlein(void);
        void StealWork(void);
    };

    ...and this way you could avoid multiple inheritance and all its glorious problems, by extending the branch of inheritance I called Alien. Otherwise, you would have to continue making new classes for each new derived alien class - exponentially increasing the amount of classes you have to make.
    You've avoided multiple inheritance by creating two classes that can't do anything -- BureaucratAlien can't be an Alien-via-Mammal so there's no way to use any of those functions. You could, of course, continue your scheme, but that would entail exponentially increasing the amount of constructors there are.

  15. #15
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I don't think multiple inheritance is too problematic if you avoid the diamond, and eventually someone is going to want:

    Code:
    Alien(Hair hair, Scales scales): Mammal(hair), Reptile(scales)
    Basically the only difference seems to be whether you have one typename referring to multiple types and having multiple constructors, or you have multiple types each with one constructor.

    What would the following result in?

    Code:
    Alien aliens[2] = Alien(hair), Alien(scales);
    Last edited by anon; 09-04-2009 at 03:57 PM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 06-08-2009, 03:03 PM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. NAQ: Everything you never wanted to know about CPP
    By evildave in forum C Programming
    Replies: 21
    Last Post: 12-12-2005, 10:56 AM
  4. inheritance and performance
    By kuhnmi in forum C++ Programming
    Replies: 5
    Last Post: 08-04-2004, 12:46 PM
  5. Inheritance vs Composition
    By Panopticon in forum C++ Programming
    Replies: 11
    Last Post: 01-20-2003, 04:41 AM