2012-01-15 30 views
7

No es este código:acceso a los datos privados de los miembros de la clase externa en la clase interna

#include <iostream> 

class Outer{ 
    int a; // private data member of class Outer 
public: 
    Outer(): a(55){} 
    class Inner{ 
    public: 
     void fun(Outer ob){ 
      std::cout << ob.a << std::endl; 
     } 
    }; 
}; 

int main() { 

    Outer::Inner object; 
    object.fun(Outer()); // prints 55 
    //std::cout << (Outer().a) << std::endl; error: 'int Outer::a' is private 

    return 0; 
} 

qué clase interna tiene acceso a los datos de los miembros privados 'a' de la clase externa? Siguiendo este artículo XL C/C++ V8.0 for Linux, no debería compilarse, sin embargo se compila en g ++ 4.4.0.

Respuesta

4

De acuerdo con el documento XL C/C++ V8.0 no es compatible con C++ 11, consulte la sección "Cumplimiento de los estándares de idioma".

El compilador compatible con las siguientes especificaciones del lenguaje de programación de C y C++:

  • ISO/IEC 9899: 1999 (C99)
  • ISO/IEC 9899: 1990 (denominado C89)
  • ISO/IEC 14882: 2003 (referido como estándar de C++)
  • ISO/IEC 14882: 1998, la primera especificación oficial de la lengua (referido como C++ 98)

El estándar actual dice (ISO/IEC 14882: 2011 11.7):

Una clase anidada es miembro y como tal tiene los mismos derechos de acceso como cualquier otro miembro. Los miembros de una clase adjunta no tienen acceso especial a los miembros de una clase anidada; las reglas de acceso usuales (Cláusula 11) deben ser obedecidas.

En el estándar de idioma anterior, si este acceso no estaba permitido o, al menos, no estaba claro si debería permitirse, dependiendo de su interpretación.

+0

No, ese artículo también dice que la clase interna no tiene acceso a la clase adjunta. Pero tienes razón de que es perfectamente válido. – hvd

+0

@hvd: creo que tienes razón, editado. Tuve que volver a leerlo un par de veces porque parece un poco confuso. –

+0

De hecho, es perfectamente válido, pero (presumiblemente cuando IBM escribió su documentación y compilador) no era válido originalmente: se hizo válido por http://www.open-std.org/JTC1/SC22/WG21/docs /cwg_defects.html#45 – hvd

8

C++ estándar 03 $ 11.8/1: [class.access.nest]

Los miembros de una clase anidada no tienen acceso especial a los miembros de una clase envolvente, ni a clases o funciones que han otorgado amistad a una clase que los encierra; las reglas de acceso usuales (cláusula 11) deben ser obedecidas. Los miembros de una clase adjunta no tienen acceso especial a los miembros de una clase anidada; las reglas de acceso usuales (cláusula 11) deben ser obedecidas.

Pero esto es un defecto:

45. Access to nested classes

En C++ 11, esto se ha corregido: en 11 clases anidadas C++ no tienen acceso a los miembros privados de la clase envolvente (aunque la clase adjunta todavía no tiene acceso a miembros privados de las clases anidadas).

C++ estándar 11 11.7 clases anidadas: dice

Una clase anidada es miembro y como tal tiene los mismos derechos de acceso como cualquier otro miembro. Los miembros de una clase adjunta no tienen acceso especial a los miembros de una clase anidada; las reglas de acceso usuales (Cláusula 11) deberán obedecerse.[

class E { 
    int x; 
    class B { }; 
    class I { 
    B b; // OK:E::I can accessE::B 
    int y; 
    void f(E* p, int i) { 
     p->x = i; // OK:E::I can accessE::x 
    } 
    }; 
    int g(I* p) { 
    return p->y; // error:I::y is private 
    } 
}; 
—end example] 

El ejemplo es similar a la que tiene en cuestión y que muestra claramente su comportamiento válida.

Cuestiones relacionadas