Suggestion: Allow Multiple Inheritance and still preserver super() functionality

Russell Lewis webmaster at villagersonline.com
Thu Mar 6 09:16:04 PST 2008


Funny, just yesterday my professor gave a lecture on "why multiple 
inheritance seems like a good idea but is really hard to make work in 
practice."  (I'm in graduate school.)

The problem with MI isn't a syntax problem; there are a series of 
fundamental problems that are very hard to solve.  First is the "Diamond 
Problem," which I won't discuss here because Wikipedia has a good page 
on it:
	http://en.wikipedia.org/wiki/Diamond_problem

Another problem has to do with the binary layout of classes.  With 
single inheritance, you can define the binary layout of a class, and 
then require that any of its descendants preserve that layout.  That is, 
if you have
	class A { int x; }
	class B : A { int y; }

Then the binary layout of B is:
	+--------------------------+
	| exact copy of A's fields |
	+--------------------------+
	|      new B fields        |
	+--------------------------+

This makes it possible to convert a pointer-to-B to a pointer-to-A (and 
vice-versa) without any complexity or rewriting; it just works.  This is 
particularly important for methods, which the child might override, 
since you can call the methods using a pointer-to-A.  The calling 
function can pass the pointer-to-A as the implicit "this" pointer 
without knowing that the called function will interpret this as a 
pointer-to-B.  This works elegantly because the two pointers have the 
same binary representation.

Problem is, if a class has two parents, then you can't make that 
assumption.  You could include both of the parents whole, by value, but 
then you can't solve the diamond problem, and also you can't call 
overridden functions (because the "this" pointer for one of the parents 
is different than the "this" pointer of the child).

You can solve this, but it's costly in terms of language complexity and 
runtime performance.

Experience has shown that single-inheritance-with-interfaces is a much 
more practical solution for C-family languages.

Russ

Jim Gadrow wrote:
> Now, maybe I'm just ignorant because I've never written a compiler, but why isn't it possible to allow for something like the example following in the language?
> 
> I will first state that I don't like the super() function because I don't believe the keyword 'super' very clearly identifies what is going on. wouldn't parent() have been more suitable?
> 
> Anyways, the example:
> 
> import std.stdio;
> 
> interface A {
>     void myFoo ();
> }
> 
> interface B {
>     void myBar ();
> }
> 
> class C : A
> {
>     this ()
>     {
>         writefln ("Constructing a C...");
>     }
> 
>     void myFoo ()
>     {
>         writefln ("I've been foo'd!");
>     }
> }
> 
> class D : B
> {
>     this ()
>     {
>         writefln ("Constructing a D...");
>     }
> 
>     void myBar ()
>     {
>         writefln ("I've been bar'd!");
>     }
> }
> 
> class E : C, D
> {
>     this ()
>     {
>         parent.C ();    //Calls constructor of parent class C
>         parent.D ();    //Calls constructor of parent class D
>     }
> 
>     void myFooBar ()
>     {
>         myFoo ();
>         myBar ();
>     }
> }
> 
> void main ()
> {
>     E myClass;
>     myClass.myFooBar ();
> }
> 
> Running the program should output:
> Constructing a C...
> Constructing a D...
> I've been foo'd!
> I've been bar'd!
> 
> Obviously, the same rule would apply for inheriting multiple classes as for inheriting multiple interfaces in that something like:
> 
> class D : C, C
> 
> Would cause a compile error.



More information about the Digitalmars-d mailing list