Error: 'this' is only defined in non-static member functions, not parse
Timon Gehr
timon.gehr at gmx.ch
Tue Jan 17 11:25:28 PST 2012
On 01/17/2012 06:58 PM, Matej Nanut wrote:
> On 17 January 2012 18:29, Timon Gehr<timon.gehr at gmx.ch> wrote:
>> I'm quite sure that the error in your code occurs for the same reason as in
>> the following code snippet:
>>
>> class C{
>> class D{}
>> static make(){return new D();} // error
>> }
>>
>> You can fix it by making D static:
>>
>> class C{
>> static class D{}
>> static make(){return new D();} // ok
>> }
>>
>> The reason is that non-static inner classes have an implicit 'outer'
>> property that links to the class it was created with. Therefore, to
>> construct them inside a member function, the implicit 'this' pointer is
>> needed. If the 'outer' property is actually unwanted, it is best to declare
>> inner classes as static.
>
> Yes! If I move the class and its subclasses out of its outer class, and declare
> them all static, it works!
>
> Note that your `make' function is being called within class `D' in my example,
> if I replace the names. However, the same thing applies.
>
> Your explanation was nice, but now I'd like to know what the difference of a
> non-static vs. a static class is, if they're defined top-level? Or are they then
> the same?
Indeed they are the same. Anything top-level is implicitly static in D.
> I don't expect anyone to thoroughly explain things to me, but
> pointing out a good source, like a link or a book, would be really helpful.
>
I don't know if there is any, but I can explain to you the difference
between static and non-static nested classes in detail:
class A{
int x;
static class B{void echo(){writeln(x);}} // n.g.
}
class A{
int x;
class B{void echo(){writeln(x);}} // ok
}
In other words, non-static nested classes can reference non-static
fields of the enclosing class. In order to provide that functionality,
non-static nested classes need the implicit 'outer' field. The first
snippet is effectively rewritten to something like the following:
class A{
int x;
class B{A __outer; void echo(){writeln(__outer.x);}
}
Therefore, for constructing a class instance of type A.B, an instance of
A must be provided as an initializer for the 'outer' field. If an
instance of B is created in a member of A, the 'this' pointer gets used
(and hence is required to be present), but you can also do:
void main() {
auto a = new A;
auto b = a.new B; // construct an 'A.B' with 'a' in implicit
'outer' field
a.x = 100;
b.echo(); // writes '100'
}
This is probably one of the more obscure features of D. =)
> I lack general knowledge in the OOP area and must really learn more about
> it, as I've always been programming in C and could easily get away with it
> as we were doing small-ish programs at university.
More information about the Digitalmars-d-learn
mailing list