• Advertisement

Archived

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

when is multiple inheritance bad?

This topic is 5509 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i have a few classes that inherit from multiple classes. one is a ogg vorbis class that inherits from a resource class that all my loaded objects derive from. the other thing it inherits from is a thread class for looping in the background. is this bad? if not, what is? [edited by - billybob on January 21, 2003 9:22:25 PM]

Share this post


Link to post
Share on other sites
Advertisement
There are several reasons to avoid MI, but if you do use it always try to avoid a diamond-shaped inheritance hierarcy. In your example, I would probably privately inherit from the thread class or maybe have a thread object attribute.

[edit] Doesnt your sound library do the required threading for you anyway?

[edited by - sark on January 21, 2003 12:57:40 AM]

Share this post


Link to post
Share on other sites
nope, its openal, so it has to periodically update to queue more buffers with the music data before it runs out.

diamond shaped?

Share this post


Link to post
Share on other sites
quote:
Original post by billybob
diamond shaped?


A diamond-shaped inheritance hierarchy looks like this:



A
/ \
B C
\ /
D



Where A is the root base class and D is at the top of the hierarchy. This can cause ambiguity problems. I dont remember the specifics, but diamond shapes are a pain in the arse and can almost always be avoided.

Share this post


Link to post
Share on other sites
the problem occurs when B and C have a function named the same thing that takes the same parameters. Incredibly nasty stuff happens (sometimes compile errors, sometimes runtime errors)...

I have yet to see a nastier-to-trace bug than one I had with diamond inheritance...

Share this post


Link to post
Share on other sites
When you want to follow Object Oriented Paradigms.

Share this post


Link to post
Share on other sites
quote:
Original post by xaxa
When you want to follow Object Oriented Paradigms.



You need it when you have pure virtual baseclasses representing "interfaces" in C++, something which is used quite a bit in C++ OO methodology.


Share this post


Link to post
Share on other sites
oh, these are just really simple classes. CResource is the base class for anything that is loaded from a file, has a 32 bit id number, file name, type, and stuff like that. it doesn''t inherit from anything. the thread class is just a simple thread, it has like 3 public functions, doesn''t inherit from anything. so i take it this is safe

Share this post


Link to post
Share on other sites
quote:
always try to avoid a diamond-shaped inheritance hierarcy

Diamond shaped is sometimes a great solution. I used to oppose it too but then I stumbled across a problem that could be perfectly solved with it. The hierarchy looked like this:

A
/|\
/ | \
B C D
| /|\ |
|/ | \|
E F G
| / \ |
|/ \|
H I

It was actually quite a bit more complex but I drew the simplified version.

The only other solution I came up for the problem I had was to use the bridge pattern. But bridge was hugely more bloated and didn''t add any benefits, so why would I fanatically oppose weird looking multiple inheritance if it happens to be the most suitable solution?-)

Share this post


Link to post
Share on other sites
quote:
Original post by billybob
when is multiple inheritance bad?

When is inheritance bad? Inheritance is a mechanism for sharing commonality across multiple classes. In static languages like C++, it is also a means of allowing the compiler to verify the IS-A relationship at compile-time, so that inheritance means two things in C++: it is a code-sharing (mix-in) mechanism, and it is a means of re-introducing some limited amount of polymorphism into a language which enforces non-polymorphism as the default. Problems occur when these two concerns get confused. For example, people inherit a base class in order to mix-in some common code, and then find they have a meaningless "IS-A" relationship. Often, it is better to attempt aggregation / delegation before resorting to inheritance, although C++ does not do delegation well either. See: C++ Support for Delegation. However, although delegation can involve a lot of code replication, it does avoid the confused semantics of inheritance, which is potentially a bigger problem.

Multiple inheritance introduces yet another problem. Adding to the confusion of inheritance serving two concerns, in C++ classes also serve a dual role: they are both the building block of the object system and a namespace for resolving the meaning of symbols. When multiply-inheriting two classes, the symbol-tables clash together. With no means of determining precedence, this potentially creates naming conflicts. Further code replication is then required to disambiguate the conflicts. Nice, huh?
quote:

i have a few classes that inherit from multiple classes. one is a ogg vorbis class that inherits from a resource class that all my loaded objects derive from. the other thing it inherits from is a thread class for looping in the background. is this bad?

The odds say "yes", but your description is insufficient to tell for sure.

[edited by - SabreMan on January 22, 2003 9:10:06 AM]

Share this post


Link to post
Share on other sites
Well, according to Sun Microsystems, multiple inheritance creates more problems than it solves, which is why they disallowed it in Java and provided the programmer with "interfaces" instead.
An interface is a source file that defines method prototypes. By "implementing" an interface in a class, the programmer is forced to implement all the methods that are defined in the interface.

I found this way of doing things very "human-brain-compatible". It probably could be done the same way in C++.

Share this post


Link to post
Share on other sites
quote:
Original post by FiveFootFreak
Well, according to Sun Microsystems, multiple inheritance creates more problems than it solves

That''s because they took the moronic MI of a certain language as their model. This is FUD on Sun''s part, as not all languages with MI are quite as FUBAR.
quote:

which is why they disallowed it in Java and provided the programmer with "interfaces" instead.

Another argument says that they disallowed it in Java because it is complex to implement and would have affected their time-to-market. They then built marketing hype to rationalise their business decisions into looking like benevolent technical decisions.
quote:

I found this way of doing things very "human-brain-compatible".

What''s that supposed to mean? It sounds more like "it makes it harder for my brain to get confused, as my choices are restricted for me".
quote:

It probably could be done the same way in C++.

It *can* be done the same stupid way in C++. What makes you think removing MI was what led to the ability to define abstract classes?

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
When multiply-inheriting two classes, the symbol-tables clash together. With no means of determining precedence, this potentially creates naming conflicts. Further code replication is then required to disambiguate the conflicts. Nice, huh?
But how could this be done better? In C++, when ambiguousness occurs, you explicitely state what you really want (object.Base::var = 2). I think it''s just natural. In Python the symbols are checked in left-to-right order from the base classes, which removes ambiguousnesses but makes it a bit uncertain which method you''re actually calling (hmm I hope I didn''t make any mistakes, I''ve yet to write a Python proggie, I''ve just read some tutorials )

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Actually the nasty thing with multiple inheritance is not about introducing ambiguousness in the code we write as this is easily solved as stated above. Simply put multiple inheritance can be a vicious performance killer because of two things.

The not so horrible problem is data member alignment. An instantiated object C that inherits from both objects A and B can align the data members of A and B in two ways...

----------------
| Members of A |
----------------
| Members of B |
----------------
| Members of C |
----------------

or the other way around

----------------
| Members of B |
----------------
| Members of A |
----------------
| Members of C |
----------------

The problem lies within all methods that access the data members of A and B. Overhead is introduced to all data accessing.

The second and major performance problem with multiple inheritance is polymorphism (read virtual methods). It is simply pure hell to determine which method to look up in the virtual pointer table.


I tend to avoid multiple inheritance like the plague as most inheritance can be resolved with a ''has'' relationship. Multiple inheritance is often but not always a clear signal of poor OO design.

For those who are interested i recomend the book <a href="http://www.accu.org/bookreviews/public/reviews/i/i000633.htm">Inside the C++ object model</a>

Share this post


Link to post
Share on other sites
quote:
Original post by MadKeithV
Original post by xaxa
When you want to follow Object Oriented Paradigms.


You need it when you have pure virtual baseclasses representing "interfaces" in C++, something which is used quite a bit in C++ OO methodology.





Yes, but you don't inherit an interface. You implement it. Multiple inheritance from two (or more) common clases is forbidden in OO paradigm.

EDIT: Multiple inheritance of quotes is also forbidden here..

[edited by - xaxa on January 22, 2003 11:17:09 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by xaxa
Multiple inheritance from two (or more) common clases is forbidden in OO paradigm.

Says who?



"The fact that a believer is happier than a skeptic is no more to the point than the fact that a drunken man is happier than a sober one." -- George Bernhard Shaw

Share this post


Link to post
Share on other sites
Although it''s not forbidden in OO, it is good to avoid it. One of the great things things programmers try to do when writing an OO program is reduce coupling and cohesion between the external and internal systems respectfully. When you use mi, you increase coupling which partialy defeats the purpose of OO. Although you can still program in OO using multiple inheritence, you could consider it as a taboo. Just my 2 cents.

"Flies are born the size they are" -- Undisclosed Person

Share this post


Link to post
Share on other sites
quote:
Original post by xaxa
Yes, but you don''t inherit an interface. You implement it. Multiple inheritance from two (or more) common clases is forbidden in OO paradigm.
Ohmigod. I never knew Sun''s brainwashing was THIS successful.

Share this post


Link to post
Share on other sites
hehe, believe it.......it runs deeper than the marianas trench.

"Flies are born the size they are" -- Undisclosed Person

Share this post


Link to post
Share on other sites
Have *you* ever tried to breed a cheetah with a kangaroo? Believe me, the result is not pretty :b

Same thing goes with a resource and a thread. When is a thread a resource? Never. Those are two completely different beasts. A thread is a runnable process, and a resource holds data or functionality. Why can''t the thread have a pointer to the resource?

BTW, in Java you can use the Runnable interface. It just has one function run(), and the generic Thread class calls it once it has created the thread. It''s very generic and very useful, since you can run any class as a thread just by adding a few lines of code.

Tom

Share this post


Link to post
Share on other sites
i''ve looked and this is the only MI class i can find, the reason it inherits from resource is so i can use a generic resource manager to load all my assets, and keep them organized in general. the one and ONLY reason it inherits from a thread is so it can loop in the background checking if the buffers need to be queued. i don''t use the thread as polymorphism or whatever, only for the thread function. the fact that it derives from thread is completely non-existant unless you look at the class definition. i COULD make it a single inheritance by re-programming my thread stuff in the class, but i don''t see the point, it doesn''t seem worth it.

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
What''s that supposed to mean? It sounds more like "it makes it harder for my brain to get confused, as my choices are restricted for me".



I like this feature of Java. It is easy to use MI in a confusing and bad fashion so removing it reduces the chance a less experienced programmer will make code that is difficult to work with. I''ve heard of many C++ advocates that don''t like this restriction, but the fact is that most programmers are far from perfect and features like this and others in Java, the most obvious one being garbage collection (I know C++ can use one but I''ve frankly never seen this outside an academic scope), create better code in my opinion. MI might be a natural solution to some problems, but I feel the hassle of using a less suited implementation is a very reasonable tradeoff to the benifits.

Share this post


Link to post
Share on other sites
quote:
Original post by apatequil
Although it''s not forbidden in OO, it is good to avoid it. One of the great things things programmers try to do when writing an OO program is reduce coupling and cohesion between the external and internal systems respectfully. When you use mi, you increase coupling which partialy defeats the purpose of OO. Although you can still program in OO using multiple inheritence, you could consider it as a taboo. Just my 2 cents.


I guess forbidden isn''t the right word. And I meant Pure OO.

Share this post


Link to post
Share on other sites
quote:
xaxa: I meant Pure OO.


can you provide a link to some websites expanding on your definition of ''pure oo''?

Share this post


Link to post
Share on other sites

  • Advertisement