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