Multiple subtyping with alias this and nested classes

Max Samukha spambox at d-coding.com
Fri Oct 2 11:41:54 PDT 2009


On Fri, 02 Oct 2009 13:00:05 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:

>I just realized that nested classes work so well with alias this, you'd 
>think it was an evil plot all along. It wasn't, but I'm happy about the 
>coincidence.
>
>Here's how to effect multiple subtyping in D very effectively:
>
>import std.stdio;
>
>class Base1 {
>     void fun() { writeln("Base.fun"); }
>}
>
>class Base2 {
>     void gun() { writeln("Base.fun"); }
>}
>
>class Multiple : Base1 {
>     // Override method in Base1
>     override void fun() { writeln("Multiple.fun"); }
>     // Override method in Base2
>     class MyBase2 : Base2 {
>         override void gun() { writeln("Multiple.gun"); }
>     }
>     // Effect multiple subtyping
>     Base2 _base2;
>     alias _base2 this;
>     this() {
>         _base2 = new MyBase2;
>     }
>}
>
>void main()
>{
>     auto obj = new Multiple;
>     Base1 obj1 = obj;
>     obj1.fun();
>     Base2 obj2 = obj;
>     obj2.gun();
>}
>
>The program above segfaults because somehow obj2 is null. That is a bug 
>I just reported. For now, you can replace obj2.gun() with obj.gun() to 
>make things work.
>
>When we first introduced alias this, I knew multiple subtyping was 
>possible. I didn't expect it to dovetail so nicely with nested classes.
>
>
>Andrei

Neat! But what if there is Base3? Is it supposed to be subtyped like
this:

class Base3
{
     void run() {}
}

class Multiple : Base1 {
     // Override method in Base1
     override void fun() { writeln("Multiple.fun"); }
     // Override method in Base2
     class MyBase2 : Base2 {
         class MyBase3 : Base3
         {            
              override void run() { writeln("Multiple.run"); }  
         }
        MyBase3 _base3;
        this() { _base3 = new MyBase3; } 
        alias _base3 this;
                      
         override void gun() { writeln("Multiple.gun"); }
     }
     // Effect multiple subtyping
     MyBase2 _base2;
     alias _base2 this;
     this() {
         _base2 = new MyBase2;
     }
}
?

Note that there is an additional level of indirection per each
subtype:

auto m = new Multiple;

m.run is unrolled to m._base2._base3.run



More information about the Digitalmars-d mailing list