On 01/17/2012 06:58 PM, Matej Nanut wrote:
On 17 January 2012 18:29, Timon Gehr<timon.g...@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.