Are inner classes in C++ automatically friends?
C++FriendNested ClassC++ Problem Overview
If I define an inner class in C++, is it automatically a friend of the class that contains it? For example, is this legal:
class Outer {
public:
class Inner {
public:
void mutateOuter(Outer& o);
};
private:
int value;
};
void Outer::Inner::mutateOuter(Outer& o) {
o.value ++; // Legal? Or not?
}
I ask because on some compilers I've tried (VS2003) this code won't work, but I've heard at least anecdotally that it does work on some compilers. I can't find a relevant section in the C++ spec about this, and if anyone can cite something specific that would say that it is or is not legal that would be great.
C++ Solutions
Solution 1 - C++
After having asked more or less the same question here myself, I wanted to share the (apparently) updated answer for C++11:
Quoted from https://stackoverflow.com/a/14759027/1984137:
> standard $11.7.1 > > "A nested class is a member and as such has the same access rights as > any other member. The members of an enclosing class have no special > access to members of a nested class; the usual access rules shall be > obeyed" > > and the usual access rules specify that: > > "A member of a class can also access all the names to which the class > has access..." > > specific examples has been given in the standard:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
}
Solution 2 - C++
Until C++11 (i.e C++98 and C++03)
In C++98 and C++03, nested class cannot access private
and protected
members of enclosing class by default.
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.
Example from the Standard itself:
class E
{
int x;
class B { };
class I
{
B b; // error: E::B is private
int y;
void f(E* p, int i)
{
p->x = i; // error: E::x is private
}
};
int g(I* p)
{
return p->y; // error: I::y is private
}
};
Since C++11
The above restriction has been removed since C++11. Now the nested classes can access the private
and protected
members of the enclosing class:
class E
{
int x;
class B { };
class I
{
B b; // ok: even though E::B is private
int y;
void f(E* p, int i)
{
p->x = i; // ok: even though E::x is private
}
};
int g(I* p)
{
return p->y; // ok: even though I::y is private
}
};
Hope that helps.
Solution 3 - C++
Since the questioner seems to have accepted one of the answer, this is just
a supplementation.
The standard seems to have changed the specification about the accessibility.
§11.8/1 in C++98 states:
> 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 shall be obeyed.
§11.8/1 in N1804(after TR1) states:
> A nested class is a member and as such > has the same access rights as any > other member.
I think current C++ compilers obey newer specification.
Solution 4 - C++
This answer pertains to the (outdated) C++03 specification. The accepted answer at this question is more up to date.
Well, I feel silly for asking this question now because I just found the relevant part of the spec that covers this: §11.8/1:
> 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
(My emphasis)
So it looks like no, inner classes do not have special access privileges.
Solution 5 - C++
I don't the precise location off the top of my head, but I do recall reading through the specs and finding that any private data in a class is hidden from all other classes, including nested classes.
Basically, nesting a class defines a certain scope, not access priviledges.