inner member classes in final outer class

Regan Heath regan at netmail.co.nz
Sun Sep 16 03:58:42 PDT 2007


Kirk McDonald wrote:
> coxalan wrote:
>> Frits van Bommel Wrote:
>>
>>
>>> I just looked it up; from the documentation (the page you linked
>>> above): ===== Non-static nested classes work by containing an extra
>>> hidden member (called the context pointer) that is the frame
>>> pointer of the enclosing function if it is nested inside a
>>> function, or the this of the enclosing class's instance if it is
>>> nested inside a class. =====
>>>
>>> In the code above the class is nested in another class (not a
>>> function), so the context pointer is the 'this' of the enclosing
>>> class, i.e. a copy of 'o'.
>>
>>
>> Yes, the "this" of the outer class is stored in each inner member
>> class. So on a 32 bit machine: Each inner class contains 4 extra
>> bytes storing the address of the outer class (This is what I meant by
>> using the term "pointer": An address is stored.)
>>
>> In my code example, the outer class 'o' is final. That means that the
>> reference stored in 'o' will never change, so for all instances of
>> 'o.Inner' the address stored in the context pointer will be the same.
>> This is redundant, and I wonder if the optimization could be done to
>> _not_ store the reference pointers for instances of member classes of
>> final outer classes.
> 
> That o is final is irrelevant. Consider:
> 
> Outer.Inner foo() {
>     final Outer o = new Outer;
>     return o.new Inner;
> }
> 
> The lifetime of the instance of the Inner class can easily exceed that 
> of the original reference to the instance of the Outer class which 
> created it. Therefore, the Inner class must have its own reference to 
> the Outer class.

Must it?  What if the inner classes had a static reference to the outer?
eg.

class Outer
{
   class Inner
   {
     static Outer outer; //only one copy for all instances of Inner
   }
}

So, if you have X instances of Outer, creating Y instances of Inner you 
will have only X outer references, instead of X*Y outer references.

The static reference will prevent the destruction of the outer when it 
leaves scope in your example above, but when will it be destroyed?  How 
does D currently deal with this in a normal "class contains static 
reference" situation?  Are these objects destroyed only at program exit?

I'm not sure I understand how static references or even normal members 
are implemented, are they implemented in the same was as global variables?

Should static outer references be the default behaviour?  It seems to be 
a neat little optimisation, assuming it doesn't cause destruction 
problems as described above and maybe even then.

The only case I can imagine wanting a seperate outer reference for each 
inner class is when I need to move inner classes from one outer to 
another, eg

auto o = new Outer;
auto p = new Outer;
auto i = new o.Inner;
i.outer = p;

I'm not sure this is even possible currently and I can't think of a 
reason why you might want to do this.

Regan



More information about the Digitalmars-d mailing list