C++ Nested Classes Accessibility

C++ nested classes accessibility

Question 1> Is it true that OutSideClass can ONLY access public members of InSideClass

Yes

Question 2> Is it true that InSideClass can access all members of OutSideClass

No, in C++03. Yes, in C++11.


The Standard text is very clear about this:

The C++ Standard (2003) says in $11.8/1 [class.access.nest],

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 (clause 11)
shall be obeyed. The members of an enclosing class have no special
access to members of a nested class; the usual access rules (clause
11) shall be obeyed.

However, the Standard quotation has one defect. It says the nested classes don't have access to private members of the enclosing class. But in C++11, it has been corrected: in C++11, nested classes do have access to private members of the enclosing class (though the enclosing class still doesn't have access to private members of the nested classes).

See this Defect Report :

  • 45. Access to nested classes

Accessibility and Visibility in Nested Class C++

What you've created here is a nested class: The name of the nested class exists in the scope of the enclosing class, and name lookup from a member function of a nested class visits the scope of the enclosing class after examining the scope of the nested class.

When you refer to x within Test1::Test2::m() in your example, the compiler is going to go up the scope chain and find the first x to be Test1::x. Because this isn't a static member variable you're getting the error.

If you want to refer to the global x use ::x. I modified your example to demonstrate:

#include <stdio.h>

int x = 0;
class Test1{
public:
char *x;
class Test2{
public:
int m(){
return ::x++;
}
};
};

int main() {
printf("x = %d\n", x);
Test1::Test2 foo;
foo.m();
printf("x = %d\n", x);
return 0;
}

This prints:

x = 0
x = 1

$.02 note on style: If you reserve nested classes for simple data containers that only operate on themselves, as is a common best practice, you won't run into this issue.

Can enclosing class access nested class?

Can enclosing class access nested class?

Yes, if the enclosing class have an instance (an object) of the nested class.

A class is a class is a class... Nesting doesn't matter, you must always have an instance of the class to be able to call a (non-static) member function.

nested class access control in C++

This issue has been addressed in Defect Report #10 and Defect Report #45.

The original and the current C++ language standard does not grant the nested class any extra access rights, i.e. it has no privileges when accessing members of the enclosing class. Nested classes are just ordinary completely independent classes, which just happen to be declared inside some other class.

But according to the proposed resolution in the Defect Report #45, the nested class should be given full access rights to the members of the enclosing class. I.e. the nested class should itself be considered a member of the enclosing class and should enjoy all access rights normally granted to members.

Last time I checked, the work on this defect was not finalized yet. Some compilers already implement what they think the new specification will require, i.e. full access rights to nested classes (see the proposed resolution to the DR#45). Some compilers stick to the letter of the current standard. This is why you might still observe some inconsistency between different compilers with regard to access rights granted to nested classes.

Nested class member access on C++11

To close this question I'll take this as an answer:

"No, it's not treated as a member of the class, it's just scoped inside of it like anything else. You'll need an instance of Enclosing to access it's members."

  • this and several other comments addresses the problem in my code. Basically this is something that remains true for C++11.

Does an in-class friend of a nested class have access to outer class members?

I think gcc and msvc are right.

From [class.friend]/1, emphasis mine:

A friend of a class is a function or class that is given permission to use the private and protected member names from the class. A class specifies its friends, if any, by way of friend declarations. Such declarations give special access rights to the friends, but they do not make the nominated friends members of the befriending class.

When you have friend E f1(), that gives f1 permission to use the private and protected names of B, specifically. E is not a private or protected name of B, it's a name that B simply has access too.


This is conceptually similar to [class.friend]/10:

Friendship is neither inherited nor transitive.

Since it would imply that the rule is that f1 can access B's stuff, and B can access A's stuff, therefore f1 can access A's stuff.



Related Topics



Leave a reply



Submit