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