This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115e. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-11-11
[Moved to DR at 4/01 meeting.]
Example:
#include <iostream.h> class C { // entire body is private struct Parent { Parent() { cout << "C::Parent::Parent()\n"; } }; struct Derived : Parent { Derived() { cout << "C::Derived::Derived()\n"; } }; Derived d; }; int main() { C c; // Prints message from both nested classes return 0; }How legal/illegal is this? Paragraphs that seem to apply here are:
11.8 [class.access] paragraph 1:
A member of a class can beand 11.8.8 [class.access.nest] paragraph 1:
- private; that is, its name can be used only by members and friends of the class in which it is declared. [...]
The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules (11.8 [class.access] ) shall be obeyed. [...]This makes me think that the ': Parent' part is OK by itself, but that the implicit call of 'Parent::Parent()' by 'Derived::Derived()' is not.
From Mike Miller:
I think it is completely legal, by the reasoning given in the (non-normative) 11.8.8 [class.access.nest] paragraph 2. The use of a private nested class as a base of another nested class is explicitly declared to be acceptable there. I think the rationale in the comments in the example ("// OK because of injection of name A in A") presupposes that public members of the base class will be public members in a (publicly-derived) derived class, regardless of the access of the base class, so the constructor invocation should be okay as well.
I can't find anything normative that explicitly says that, though.
(See also papers J16/99-0009 = WG21 N1186, J16/00-0031 = WG21 N1254, and J16/00-0045 = WG21 N1268.)
Proposed Resolution (04/01):
Insert the following as a new paragraph following 11.8 [class.access] paragraph 1:
A member of a class can also access all names as the class of which it is a member. A local class of a member function may access the same names that the member function itself may access. [Footnote: Access permissions are thus transitive and cumulative to nested and local classes.]
Delete 11.8 [class.access] paragraph 6.
In 11.8.8 [class.access.nest] paragraph 1, change
The members of a nested class have no special access to members of an enclosing class, nor to classes or functions that have granted friendship to an enclosing class; the usual access rules (11.8 [class.access]) shall be obeyed.
to
A nested class is a member and as such has the same access rights as any other member.
Change
B b; // error: E::B is private
to
B b; // Okay, E::I can access E::B
Change
p->x = i; // error: E::x is private
to
p->x = i; // Okay, E::I can access E::x
Delete 11.8.8 [class.access.nest] paragraph 2.
(This resolution also resolves issues 8 and 10.