www.digitalmars.com         C & C++   DMDScript  

D - Suggestion for MI

reply "Philippe Mori" <philippe_mori hotmail.com> writes:
I understand that MI (multiple inheritance) can causes some problems
but I do believe that it has some uses. I think I have found a
compromise that would allows us to have most of the benefit
while avoiding the problems.

We could allows multiple private (non-virtual) bases so that we can
uses MI for implementation purpose or to override some virtual
functions...

In fact, I would prefer an inheritance more restrictive than in C++
(I would call it hidden) where form the outside we cannot see it
at all (no is-a relashionship).

We may support some form of delegation though by explictly
asking it (I would also like delegation to member if not already
supported).

Also, I think it would be usefull to be able to give an alias to
each base class when specifying the base... I C++, we have to
do a typedef but nothing prevent us to misspell it or to forget to
modify it when adding a class in the hierarchy.

Note that for the public base, we will still uses the super keyword.


Another solution would be to support nested objects with access
to the outer one (from the language). Maybe this could be done
from an unnamed class object or with a keyword that tell that the
class is intended to be used "nested" (and thus have access to the
outer object).
Aug 19 2003
parent reply "Philippe Mori" <philippe_mori hotmail.com> writes:
 I understand that MI (multiple inheritance) can causes some problems
 but I do believe that it has some uses. I think I have found a
 compromise that would allows us to have most of the benefit
 while avoiding the problems.

 We could allows multiple private (non-virtual) bases so that we can
 uses MI for implementation purpose or to override some virtual
 functions...

 In fact, I would prefer an inheritance more restrictive than in C++
 (I would call it hidden) where form the outside we cannot see it
 at all (no is-a relashionship).

 We may support some form of delegation though by explictly
 asking it (I would also like delegation to member if not already
 supported).

 Also, I think it would be usefull to be able to give an alias to
 each base class when specifying the base... I C++, we have to
 do a typedef but nothing prevent us to misspell it or to forget to
 modify it when adding a class in the hierarchy.

 Note that for the public base, we will still uses the super keyword.


 Another solution would be to support nested objects with access
 to the outer one (from the language). Maybe this could be done
 from an unnamed class object or with a keyword that tell that the
 class is intended to be used "nested" (and thus have access to the
 outer object).

In my case I may like MI for implementation particulary when it comes to templates (so that we can do things as in ATL for example). Note that if we support inner object with access to the outer one and automatic delegation (if desired) to inner object (including type conversion if desired), MI could be replaced: class outer { inner_class inner_type { void f() { // Here I would like access to outer... } }inner; // also indicate delegation order... } // Here I want to be able to uses inner_type like that: outer o; o.f(); // f does not exist in outer, delegate to inner.
Aug 20 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
----- Original Message ----- 
From: "Philippe Mori" <philippe_mori hotmail.com>
To: "Mike Wynn" <mike.wynn l8night.co.uk>
Sent: Wednesday, August 20, 2003 11:21 PM
Subject: Re: Suggestion for MI


 I do not see the point with virtual base classes... When doing COM,
 we do not uses virtual when inheriting an interface... so it is not a
 requirement.

I think you missed my point. interface in D IS COM interface COM interface is very very close in implemention to C++ virtual base classes COM interfaces can allow interfaces to have data members (unlike Java interfaces for instance)
 Effectively, for COM we need a distinct vtable for each interface...

and yes D does that for interfaces, thought its a bit Java in the way it creates the vtbls (based on name+signature), easily solved by createing a version of the interface with same functions params just different names to resolve name clashes.
 In my case I may like MI for implementation particulary when
 it comes to templates (so that we can do things as in ATL for
 example).

just because the ATL does something does not mean its the best way what exactly are you wishing to do.
 Note that if we support inner object with access to the outer one
 and automatic delegation (if desired) to inner object (including type
 conversion if desired), MI could be replaced:

 class outer {
     inner_class inner_type {
         void f() {
             // Here I would like access to outer...
         }
     }inner;

     // also indicate delegation order...
 }

 // Here I want to be able to uses inner_type like that:

 outer o;
 o.f();    // f does not exist in outer, delegate to inner.

or do you want to be able to subclass the inner_class outer o = new outer.other_type_of_inner(); ?? but thats just a sub class of `f`. or is inner changable at runtime. can you give an example that shows the feature/symantics you want.
Aug 20 2003
parent reply "Philippe Mori" <philippe_mori hotmail.com> writes:
 MI causes Object layout problems (hence C++ having virtual inheritance)
 just because the ATL does something does not mean its the best way
 what exactly are you wishing to do.

Maybe ATL is not the best way but it is a good example how MI can help get the functionality from multiple bases... It is true that often it would be to uses data member instead of inheriting from multiple bases but the without automatic forwarding, it is a pain to have to forward calls... Also the trick to pass the derived class as a parameter of the base allows to access things in derived and sibling class more or less easily. class A : public B<A> { ... }; And for multiple inheritence and other similar tricks that are usefull in C++, one can take a look a C++ Templates book... An example that come to my mind is an automatic pointer that inherited from multiple bases to specify policies (one base for threading, one for life managment, ...) template <typename T, ThreadModel, LifeManagment> class Pointer : public ThreadModel, public LifeManagment { };
Aug 21 2003
parent Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bi2gpa$2u4p$1 digitaldaemon.com>, Philippe Mori wrote:
 MI causes Object layout problems (hence C++ having virtual inheritance)
 just because the ATL does something does not mean its the best way
 what exactly are you wishing to do.

Maybe ATL is not the best way but it is a good example how MI can help get the functionality from multiple bases... It is true that often it would be to uses data member instead of inheriting from multiple bases but the without automatic forwarding, it is a pain to have to forward calls...

There would be two types of inheritance: 1. IS-A inheritance (or interface inheritance, public inheritance in C++) - means implementing the interface of the parent class(es) 2. IS-IMPLEMENTED-IN-TERMS-OF inheritance (aka structure inheritance, uses-a inheritance or implementation inheritance, like private inheritance in C++) - means reusing the structure (functions, members and other inner elements) of the parent class The second one can be relatively easily implemented with textual inclusion. Only problems would be how to handle several constructor calls and how to resolve name clashes (a problem that also comes up in IS-A inheritance) First one is more difficult to implement. At any case you need to take care of vtables, adjusting the pointer value of the object at run-time, checking if it's null when casting from a derived object to base object etc. If you allow full MI (of classes that have data members), it gets even more complicated when you need to decide whether to share or duplicate base classes, how to construct them and so on. We don't want that, hence no MI. But we don't necessarily need that, either. Inheritance is sometimes "abused" when the user only wants the convenience of inheriting the structure of the parent without the intention of making the inheriting class act as an instance of the inherited one. What he *really* wants is structural inheritance, which for example Sather offers with its "include" construct. I'd rather see structural inheritance than full MI, since it would be useful but cause far less problems. We could for example adopt the import statement to do structural inheritance: class A { int featureA() { return 1; } float x; } class B { import A; int featureB() { return 2; } } would result in class A's code to be injected into X -- just textual inclusion. There would be no limit for the imported classes. One use that I can think of is parameterized policy classes. There are bound to be plenty of others. About proper uses of inheritance (in C++, at least) the following articles by Herb Sutter are worthwhile reading: http://www.gotw.ca/publications/mill06.htm http://www.gotw.ca/publications/mill07.htm http://www.gotw.ca/gotw/060.htm -Antti
Aug 23 2003