inner member classes in final outer class

Regan Heath regan at netmail.co.nz
Sun Sep 16 06:18:24 PDT 2007


Bruno Medeiros wrote:
> Regan Heath wrote:
>> 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.
>>
> 
> That's wrong. You don't have X outer references, there is only one 
> instance of outer (aka Outer.Inner.outer). A static attribute in a 
> member declaration makes it unique, even if the member is an inner class.

One of us is missunderstanding something :)


I was describing this case:

class Outer
{
   class Inner
   {
   }
}

where Inner automagically has an 'outer' member which refers to the 
Outer class instance.

Described here:
http://www.digitalmars.com/d/class.html

"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."

(NOTE: I'm not referring to the class definition I gave above which was 
a fictional representation of how D _could_ implement the context 
pointer as a static reference)

Then when I said "So, if you have X instances of Outer, creating Y 
instances of Inner" I meant _if_ you code something like this:

const int X = 10;
const int Y = 10;

for(int i = 0; i < X; i++)
{
   auto o = new Outer;
   for(int j = 0; j < Y; j++)
   {
     auto i = new o.Inner;
   }
}

You will have X (10) outer objects each with Y (10) inner objects, each 
containing a context pointer to the outer object, therefore you have X*Y 
(100) context pointers.  Making the context reference static would 
decrease this number to X (10) context pointers.

Make sense, or am I missunderstanding something?

Regan



More information about the Digitalmars-d mailing list