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