www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - 126 - More nested class weirdness - inherited name hiding stuff

This kind of borders on a bug and a questionable implementation issue, but 
it's certainly not good.

class A
{
 this()
 {
  b=new B;
 }

 class B
 {
  int x() { return 5; }
 }

 B b;
}

class C : A
{
 this()
 {
  b=new B;
  // b2=new A.B;  // This is illegal for some reason -- "no 'this' for 
nested class B" ??
 }

 class B
 {
  int x()
  {
   // Next line causes a stack overflow from recursion, but I want to call 
the A.B's x(), but it's
   // not available as the C.B hides the A.B
   // return b.x+10;
   return 10;
  }
 }

 // Another b?!  But this is of type C.B, not A.B.  This overrides the A.B 
member, however,
 // and if I make this member, I can't access the A.B member anymore.
 B b;
 A.B b2;  // This is legal, however
}

void main()
{
 A a=new A;
 C c=new C;
 writefln(a.b.x); // 5
 writefln(c.b.x); // 10
 a=c;
 // This is somewhat confusing - when you upcast, there is still a "b" 
member, so it still
 // works, but returns something different.
 writefln(a.b.x); // 5
}

This shows a few problems:

1) class A has a class B, and so does C.  They are different classes, 
however, named A.B and C.B.  But note that although C inherits from A, I am 
allowed to have another member named b.

I'm not sure if this behavior was allowed before, but it seems legal to have 
members in derived classes which override members in super classes.  This 
makes sense for functions, but not really for regular members.

2) Because C's b overrides A's b, I can no longer access the A.B b member in 
C.  Thus, the commented-out return statement in C.B.x causes a stack 
overflow from infinite recursion.  There is no way for me to specify 
"super.b.x" or anything like that, as the "super" of C.B is Object.

3) I can declare an A.B member b2, but I can't initialize it.  If I try to 
use "new A.B," I get the cryptic error message "no 'this' for nested class 
B."  Weirder - I can actually make a member called "A.B b," which overrides 
the "b" member in A in both name and type.

4) In main(), I create an A and a C.  a.b.x returns 5 and c.b.x returns 10, 
as expected.  But if I cast the C to an A, it then returns 5.  This again 
stems from the name overriding issue - both A and C have a "b" member, but 
they have different properties.  Confusing.

Again, I'm not sure which of these qualify as bugs, but they certainly are 
foggy areas of the nested class spec. 
Jun 09 2005