Multiple subtyping with alias this and nested classes

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Oct 2 11:48:07 PDT 2009


Max Samukha wrote:
> 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

Multiple alias this declarations must be allowed.

Andrei



More information about the Digitalmars-d mailing list