@@ -1358,9 +1358,11 @@ void func()
1358
1358
}
1359
1359
------
1360
1360
1361
+ $(H3 $(LNAME2 static-nested, Static Nested Classes))
1362
+
1361
1363
$(P If a nested class has the $(D static) attribute, then it can not access
1362
1364
variables of the enclosing scope that are local to the stack or need a
1363
- `this`:)
1365
+ `this` reference :)
1364
1366
1365
1367
------
1366
1368
class Outer
@@ -1394,9 +1396,11 @@ void func()
1394
1396
}
1395
1397
------
1396
1398
1399
+ $(H3 $(LNAME2 nested-context, Context Pointer))
1400
+
1397
1401
$(P Non-static nested classes work by containing an extra hidden member (called
1398
1402
the context pointer) that is the frame pointer of the enclosing function if it
1399
- is nested inside a function, or the $(D this) of the enclosing class's instance
1403
+ is nested inside a function, or the $(D this) reference of the enclosing class's instance
1400
1404
if it is nested inside a class.)
1401
1405
1402
1406
$(P When a non-static nested class is instantiated, the context pointer
@@ -1425,9 +1429,9 @@ void func()
1425
1429
}
1426
1430
------
1427
1431
1432
+ $(H3 $(LNAME2 nested-explicit, Explicit Instantiation))
1428
1433
1429
-
1430
- $(P A $(I this) can be supplied to the creation of an
1434
+ $(P A `this` reference can be supplied to the creation of an
1431
1435
inner class instance by prefixing it to the $(I NewExpression):
1432
1436
)
1433
1437
@@ -1454,14 +1458,16 @@ int bar()
1454
1458
}
1455
1459
---------
1456
1460
1457
- $(P Here $(D o) supplies the $(I this) to the outer class
1461
+ $(P Here $(D o) supplies the ` this` reference to the inner class
1458
1462
instance of $(D Outer).
1459
1463
)
1460
1464
1461
- $(P The property $(D .outer) used in a nested class gives the
1462
- $(D this) pointer to its enclosing class. If there is no enclosing
1463
- class context, $(D .outer) would return a pointer to enclosing
1464
- function frame with $(D void*).
1465
+ $(H3 $(LNAME2 outer-property, `outer` Property))
1466
+
1467
+ $(P For a nested class instance, the $(D .outer) property is the
1468
+ $(D this) reference for the enclosing class's instance. If there
1469
+ is no enclosing class context, $(D .outer) would be a $(D void*)
1470
+ to the enclosing function frame.
1465
1471
)
1466
1472
1467
1473
----
@@ -1484,16 +1490,16 @@ class Outer
1484
1490
void bar()
1485
1491
{
1486
1492
// x is referenced from nested scope, so
1487
- // bar makes a closure envronment .
1493
+ // bar makes a closure environment .
1488
1494
int x = 1;
1489
1495
1490
1496
class Inner2
1491
1497
{
1492
1498
Outer getOuter()
1493
1499
{
1494
1500
x = 2;
1495
- // The Inner2 instance owns function frame of bar
1496
- // as static frame pointer, but .outer yet returns
1501
+ // The Inner2 instance has access to the function frame
1502
+ // of bar as a static frame pointer, but .outer returns
1497
1503
// the enclosing Outer class instance property.
1498
1504
return this.$(CODE_HIGHLIGHT outer);
1499
1505
}
@@ -1503,18 +1509,19 @@ class Outer
1503
1509
assert(i.getOuter() is this);
1504
1510
}
1505
1511
1512
+ // baz cannot access an instance of Outer
1506
1513
static void baz()
1507
1514
{
1508
- // make a closure envronment
1515
+ // make a closure environment
1509
1516
int x = 1;
1510
1517
1511
1518
class Inner3
1512
1519
{
1513
1520
void* getOuter()
1514
1521
{
1515
1522
x = 2;
1516
- // There's no accessible enclosing class instance, so
1517
- // .outer property returns the function frame of bar .
1523
+ // There's no accessible enclosing class instance, so the
1524
+ // .outer property returns the function frame of baz .
1518
1525
return this.$(CODE_HIGHLIGHT outer);
1519
1526
}
1520
1527
}
@@ -1525,29 +1532,48 @@ class Outer
1525
1532
}
1526
1533
----
1527
1534
1528
- $(H2 $(LNAME2 anonymous, Anonymous Nested Classes))
1535
+ $(H3 $(LNAME2 anonymous, Anonymous Nested Classes))
1529
1536
1530
1537
$(P An anonymous nested class is both defined and instantiated with
1531
1538
a $(I NewAnonClassExpression):
1532
1539
)
1533
1540
1534
1541
$(GRAMMAR
1535
1542
$(GNAME NewAnonClassExpression):
1536
- $(D new) $(GLINK2 expression, AllocatorArguments)$(OPT) $(D class) $(I ClassArguments )$(OPT) $(GLINK SuperClass)$(OPT) $(GLINK Interfaces)$(OPT) $(GLINK2 struct, AggregateBody)
1543
+ $(D new) $(GLINK2 expression, AllocatorArguments)$(OPT) $(D class) $(I ConstructorArgs )$(OPT) $(GLINK SuperClass)$(OPT) $(GLINK Interfaces)$(OPT) $(GLINK2 struct, AggregateBody)
1537
1544
1538
- $(GNAME ClassArguments ):
1545
+ $(GNAME ConstructorArgs ):
1539
1546
$(D $(LPAREN)) $(GLINK2 expression, ArgumentList)$(OPT) $(D $(RPAREN))
1540
1547
)
1541
1548
1542
1549
which is equivalent to:
1543
1550
1544
1551
$(GRAMMAR
1545
1552
$(D class) $(GLINK_LEX Identifier) $(D :) $(I SuperClass) $(I Interfaces) $(I AggregateBody)
1546
- $(D new) $(D $(LPAREN))$(I ArgumentList)$(D $(RPAREN)) $(GLINK_LEX Identifier) $(D $(LPAREN))$(I ArgumentList)$(D $(RPAREN));
1553
+ // ...
1554
+ $(D new) $(I AllocatorArguments) $(I Identifier) $(I ConstructorArgs)
1547
1555
)
1548
1556
1549
1557
where $(I Identifier) is the name generated for the anonymous nested class.
1550
1558
1559
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
1560
+ ---
1561
+ interface I
1562
+ {
1563
+ void foo();
1564
+ }
1565
+
1566
+ auto obj = new class I
1567
+ {
1568
+ void foo()
1569
+ {
1570
+ writeln("foo");
1571
+ }
1572
+ };
1573
+ obj.foo();
1574
+ ---
1575
+ )
1576
+
1551
1577
$(SECTION2 $(LEGACY_LNAME2 ConstClass, const-class, $(ARGS Const, Immutable and Shared Classes)),
1552
1578
1553
1579
$(P If a $(I ClassDeclaration) has a $(D const), $(D immutable)
0 commit comments