inner member classes in final outer class

Bruno Medeiros brunodomedeiros+spam at com.gmail
Sun Sep 16 04:53:58 PDT 2007


coxalan wrote:
> Hello,
> 
> Consider this code:
> 
> class Outer {
>     class Inner {
>     }
> }
> 
> void main() {
>     final Outer o = new Outer;
>     o.Inner i1 = o.new Inner;
>     o.Inner i2 = o.new Inner;
>     o.Inner i3 = o.new Inner;
> }
> 
> According to http://www.digitalmars.com/d/class.html, each "o.Inner" instance contains a "context pointer" to the enclosing outer class.
> 
> But in this case the enclosing outer class "o" is final, so in my opinion there is no need to store the context pointer in i1, i2 and i3 again and again. Instead, always the address stored in the reference "o" could be used.
> 
> Now two questions:
> 
> 1) Would it be possible to have an optimization in the D compiler which removes the context pointer in the case of final outer classes? Or will that result in other problems I currently do not realize?
> 

No. Removing the context pointer would imply having different, 
incompatible versions of the Inner class, and since that alters program 
semantics the compiler cannot do that. (unless it was an incredibly 
smart compiler capable of performing whole program optimizations, 
something which at this point is like sci-fi :P). You'd have to 
explicitly state that in the program. (see below)

> 2) With the current dmd compiler, is there a way (maybe using template magic) for a similar object design which circumvents the context pointer?
> 
> A suggestion was made here:
> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=58154
> But the problem with that code is that I cannot have more than one outer class of the same type possessing inner classes.
> 
> Thanks,
> 
> coxalan

I was thinking the following:

   class Outer {
   }

   class Inner(alias outer) {
     static assert(is(outer : Outer)); // Just a check
   }

   final Outer o1 = new Outer();
   final Outer o2 = new Outer();

   void main() {
       Inner i1 = new Inner!(o1);
       Inner i2 = new Inner!(o1);

       Inner i3 = new Inner!(o2);
       Inner i4 = new Inner!(o2);
   }


Having each Inner class parameterized with an alias, is like having a 
compile-time constant member (the outer variable). This poses some 
restrictions though: the outer classes variables cannot be declared 
inside functions (because variables inside functions cannot be used as 
alias parameters), and the Inner classes are no longer compatible 
(covariant) with each other, although you can create a common Inner 
superclass.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D



More information about the Digitalmars-d mailing list