Archived

This topic is now archived and is closed to further replies.

Digital Extent

Multiple Inheritance Bad?

Recommended Posts

I remember someone said that it is a bad idea to have multiple inheritance, but why was it? I am designing a 2D sprite system and want to keep it as less API dependant as possible. So I was thinking to have a abstract data type Sprite. Then, if a derived sprite uses Direct3D it would inherit from Sprite but also would need to inherit some Direct3D functionality also. That way, say I have two different sprite class, one that uses D3D and another that uses OGL, any object that uses a sprite would be kept generalize, having only a pointer to Sprite and not worry about which API is in question. The problem is still with the specific D3DSprite or OGLSprite. Either would inherit from Sprite, but would also need to inherite from some sort of D3D or GL type object in order to be able to draw itself. Does anyone have any idea? Thanks.

Share this post


Link to post
Share on other sites
I don''t know who told you multiple inheritence is bad. My guess would be a Java programmer making excuses for the lack of multiple inheritence in Java. Anyway...

Your idea would work, but think about this approach. Create Sprite class, a D3DTarget class, and an OGLTarget class. Both ???Target classes would be Singletons. Next make a D3DSprite class and a OGLSprite class which are derived from your Sprite class. The sprite class would contain an interface for rendering the sprite. The D3DSprite and OGLSprite would implement the sprite rendering interface inheriteted from the Sprite class, using a pointer to the D3DTarget or OGLTarget Singleton class.

I hope this makes sense. Email me (dvogel [at] intercarve [dot] net) if you need any further explanation.


Regards,
Drew Vogel

Share this post


Link to post
Share on other sites
There''s nothing wrong with multiple inheritance, it''s just tricky to get right, especially in C++.

One reason, and this is apparent from your example, is that it''s sometimes used unwisely as a replacement for composition. I see no good reason why a Direct3D sprite needs to inherit from some sort of Direct3D object as well as a Sprite object. It is a sprite but it uses Direct3D. All the specialisation can be done in the derived classes of Sprite without having those derived classes needing to derive from API-specific classes too. All your classes need is some sort of reference to a Direct3D device so that they can call the appropriate functions. That can be a singleton, or passed in via the sprite''s constructor, or perhaps just passed as a parameter when the sprite needs it.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

Share this post


Link to post
Share on other sites
Nothing wrong with most features of C++ - just most C++ programmers don''t have a clue how to use them and therefore end up creating horrible code. Multiple Inheritance is one of those great sounding features that most people use without knowing why or what they are using it for.

IMHO Multiple Inheritance is no loss to the world in the current generation of modern languages. I don''t miss it.

And if I ever have to debug another badly designed system that uses MI I''ll probably rip my hair out! :-)


Merry Xmas

Share this post


Link to post
Share on other sites
i guess the only reason why people call it bad is that some programmers get carried away and try to use it even when its not making much sense *g*
and of course a few dangerous things. imagine b and c inherit from a and x inherits from b and c. you would have all the stuff of a in x too.. but twice. except youre aware of it and know how to avoid it ,-)

Share this post


Link to post
Share on other sites
*g* as i said.. except youre aware of it.. but for my taste there are too many things to keep in mind.. i dont want to think about all the time that can be spent with debugging because it was used when it wasnt necessary...

Share this post


Link to post
Share on other sites
I''ve only used MI for my smaller helper classes... I have a templated counter class, to keep track of how many instances I have and what instance I''m currently playing with. And a templated Singleton class. And I''m sure I can come up with a few others But for me MI is nice to use, sometimes. And for me those two example are valid. But I''m sure there are people who disagree

"No lies of sugar can sweeten the sournes of reality"

}+TITANIUM+{ A.K.A. DXnewbie[onMIRC]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

I remember someone said that it is a bad idea to have multiple inheritance, but why was it?



The greater the chance a particular construct has to screw up your program, the greater the care that must be taken in applying said construct. Consequently, there are quite a few that argue against these constructs altogether. Philosophical and idealogical reasons also factor into the decision.

On the other hand, practical reasons also weigh in. Often times what you want is to inherit structure along a single path and introduce interface from others. Thus Java has single inheritance with interfaces, Objective-C has single inheritance with protocols, Ruby has single inheritance with mix-ins, etc. C++ provides the basic inheritance feature without restrictions. So while MI can be useful, tread carefully and thoughtfully. Also read up on virtual inheritance. Hope it works out.

Share this post


Link to post
Share on other sites
To call back on the original problem. I have a Sprite class so that objects that need to use sprites could just use it and not worry about how it do its work.

D3DSprite of course, inherits from Sprite in its nature. However, D3DSprite involves Direct3D stuff. I could easily pass in the Direct3DDevice and it would be all the Direct3D it need. However, with any Direct3D stuff, there involve Creation/Destruction/Rebuilding/Invalidation of various objects. One example is when you Alt+Tab, you would have to destroy everything and rebuild them.

Thus, I would like to have a generalize class that does such and is abstract so that all Direct3D related class can derive from.

So, is this a good call for multiple inheritance?

Share this post


Link to post
Share on other sites
I don''t see why you want to use multiple inheritance here. The D3DSprite will inherit from sprite and...?


Don''t listen to me. I''ve had too much coffee.

Share this post


Link to post
Share on other sites
It mainly just isn''t all that useful. Many of the "has a" relationships would properly be "is a" relationships, but actually making it an "is a" is a burden. You cannot inherit off of a class of classes. You inheret off a specific class. With "has a" you can use a polymorphic base class and at run time use one of the classes derived off of it. Several template techniques use multiple inheritance. It isn''t nearly the burden there. It is still done at compile time though.

Under extreme conditions you could have an object model where a class inherits off of three classes where each class is one of a set of ten classes. That makes a thousand possible derived classes. If you actually need to use all of those at run time then you have to select with of the thousand to actually instantiate. Frigging nightmare. It is far easier to use three conditions of ten cases than one conditional of a thousand. So in many cases where multiple-inheritance would be conceptually correct it just flat out isn''t practical. It is easier to get a contrived "has a" relationship to work correctly than to use multiple inheritance even though things fall more naturally into place using it. Most people miss the elegance of a conditional running ten functions deep

If C++ was an interpretted language then maybe you could specify the bases to inherit off of at run time. If so then you would most likely see multiple inheritance used extensively. You would most likely hear people arguing that not using multiple inheritance needlessly complicates things. You got to write all this extra code for all these special cases. You have to create new classes just to get it to work. That isn''t the case though. As it is using multiple inheritance is such a burden that getting "has a" to work correctly is by no means a needless complication.

Share this post


Link to post
Share on other sites
I have used both MI and Virtual MI in games and had almost no problems with them. Many times I will implement simple classes with MI and find that composition works better. Changing from MI to composition is EASY! Just find the places where you called the inherited functions and used inherited data, and put "m_pObjectName->" or "m_objectName." in front of those statements. Works without a single complaint.

Exception: If you actually use polymorphism on that specific class and the compiler is expecting to be able to call functions polymophically, you might be in trouble. If you are just calling the functions directly, you can stick wrapper functions to emulate the inheritance you relied upon.

Example:

class Base1
{
public:
int Foo(void);
};

class Base2{

public:
int Bar(void);
};

class Derived : public Base1, public Base2
{
public:
// anything else
};



Well, this can easily become:

class Derived : public Base1
{
public:
int Bar(void) { return m_base2->Bar(); }
private:
Base2 m_base2;
};


As far as programming problems go, this really isn't that bad.

[edited by - Rick Scott on December 26, 2002 6:49:04 PM]

Share this post


Link to post
Share on other sites
The use of the term ''DependantObject'' shows that you''re trying to change a ''depends on'' relationship into an ''is a'' relationship. It would be like deriving ''Man'' from a ''PotentiallyMarriedToWoman'' class. You don''t do that, you have a ''MarriedTo'' member. D3DSprite can be different from Sprite in its choice and use of members. It doesn''t need to derive from another class. I don''t see a compelling reason for a ''Direct3DDependantObject'' to exist.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost | Asking Questions | Organising code files | My stuff ]

Share this post


Link to post
Share on other sites