Home » C++ » Are inner classes in C++ automatically friends?

Are inner classes in C++ automatically friends?

Posted by: admin November 30, 2017 Leave a comment

Questions:

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.

Answers:

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
        }
    };
}

Questions:
Answers:

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.

Questions:
Answers:

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.

Questions:
Answers:

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.

Questions:
Answers:

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.