Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are inner classes in C++ automatically friends?

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.

like image 743
templatetypedef Avatar asked Feb 16 '11 07:02

templatetypedef


People also ask

Are nested classes friends?

If the declaration of a nested class is followed by the declaration of a friend class with the same name, the nested class is a friend of the enclosing class. If the friend function is a member of another class, you need to use the scope resolution operator ( :: ).

Do inner classes have to be private?

Inner Class You just need to write a class within a class. Unlike a class, an inner class can be private and once you declare an inner class private, it cannot be accessed from an object outside the class.

What are the rules for inner class?

Rules of Local Inner Class:The scope of the local inner class is restricted to the block they are defined in. A local inner class cannot be instantiated from outside the block where it is created in. Till JDK 7, the Local inner class can access only the final local variable of the enclosing block.

Can inner classes access private members?

A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.


2 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         }     }; } 
like image 116
hcc23 Avatar answered Oct 03 '22 01:10

hcc23


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.

like image 29
Nawaz Avatar answered Oct 03 '22 02:10

Nawaz