Topic: Scope question
Author: larsn@Autodesk.COM (Lars Nyman)
Date: 15 Jun 92 21:51:12 GMT Raw View
I have a question about how scope rules apply in a situation where a name can
be found in an enclosing scope (nested or local class) and also in base class.
Some relevant (?) quotes from ARM:
ARM p185:
The nested class is in the scope of its enclosing class.
ARM p196:
Unless redefined in the derived class, members of a base class can be referred
to as if they were members of the derived class.
ARM p216:
A name that is not qualified in any of the ways described above and that is
used in a function that is a nonstatic member of class X must be declared in
the block in which it occurs or in an enclosing block, be a member of class X
or a base class of class X, or be a global name.
Consider the following code:
class Rectangle { };
class Circle { };
class Base {
public:
class Rectangle { };
};
class Outer {
public:
class Rectangle { };
class Circle { };
class Inner : public Base {
void foobar()
{
Rectangle r; // (*1)
Circle c; // (*2)
}
};
}
What will the type of the Rectangle declared at (*1) be:
- Outer::Rectangle
- Base::Rectangle
- ambiguous
What will the type of the Circle declared at (*2) be:
- Outer::Circle
- ::Circle
- ambiguous
References to ARM would be appreciated...
Author: ark@alice.att.com (Andrew Koenig)
Date: 16 Jun 92 04:21:03 GMT Raw View
In article <15976@autodesk.COM> larsn@Autodesk.COM (Lars Nyman) writes:
> I have a question about how scope rules apply in a situation where a name can
> be found in an enclosing scope (nested or local class) and also in base class.
This issue is actively under discussion in the ISO/ANSI committee.
At present, the general idea is that all names will be sought in successively
surrounding scopes, except that members of base classes that are not
overridden in derived classes are treated as members of the derived
classes. Nested classes are treated just like members.
In your example:
class Rectangle { };
class Circle { };
No problem so far.
class Base {
public:
class Rectangle { };
};
OK, class Base has a member named Rectangle.
class Outer {
public:
class Rectangle { };
class Circle { };
and class Outer has members named Rectangle and Circle.
class Inner : public Base {
void foobar()
{
Rectangle r; // (*1)
Circle c; // (*2)
}
};
}
Function foobar is a member of class Inner, which inherits member Rectangle
from class Base. Effectively, Rectangle is a member of class Inner.
Therefore, declaration (*1) is Inner::Rectangle.
Class Inner does not have a member named Circle, nor does it inherit one.
The next move is therefore to look in the surrounding scope, namely class
Outer. There is a member named Circle there, so in (*2), Circle is
Outer::Circle.
As I said, this reflects my understanding of the current state of the
discussions in the ISO/ANSI Committee. Until the standard is actually
approved, it is all subject to change. Moreover, until it is written up,
it is even easier to change. However, I personally believe that this
treatment is likely to stand -- that is, unless I've missed something obvious.
--
--Andrew Koenig
ark@europa.att.com