2011-05-12 17 views
14

Tengo el siguiente código donde la clase A declara clase B como amigo. ¿Debería la clase C, declarada dentro de la clase B, poder ver declaraciones privadas/miembros de la clase A?¿El "amigo" de una clase se extiende a las clases declaradas dentro de esa clase?

Se compila sin error con CL versión 16 (Visual Studio 2010), pero gcc g ++ versión 4.1.1 muestra el error "typedef int A :: T es privado en este contexto".

El mismo comportamiento se produce con llamadas a funciones como typedefs (que es la forma en que descubrí la diferencia).

class A { 
    friend class B; 
    typedef int T; 
}; 

class B { 
    A::T t; // ok 
    typedef A::T U; // ok 
    class C { 
     U u; // ok 
     A::T v; // compile error on gcc 
    }; 
}; 

He investigado brevemente, pero no he podido encontrar los términos de búsqueda adecuados. Todavía tengo que leer el estándar. ¿Hay alguna pregunta previa sobre el tema o mencionada en las preguntas frecuentes de C++? ¿Qué comportamiento está imitado por el estándar, si es así?

+0

Consulte http://stackoverflow.com/questions/3584385/friend-access-to-protected-nested-class. –

+0

Este código se ve bien formado para mí. Se compila en gcc 4.5.1 y comeau en línea. –

+0

Prasoon: huh. Me pregunto por qué mi gcc está desactualizado, debería instalarse nuevamente. Oh bien. ¡Gracias! –

Respuesta

9

a partir de documentos estándar., $11.4.2

declarar una clase para ser un amigo implica que los nombres de los miembros privados y protegidos de la amistad concesión clase se puede acceder en la base especificador-s y miembro declaraciones de la clase de amigos.

Un ejemplo de los documentos estándar., Ellos mismos,

class A { 
class B { }; 
friend class X; 
}; 
struct X : A::B { // OK: A::B accessible to friend 
    A::B mx; // OK: A::B accessible to member of friend 
    class Y { 
     A::B my; // OK: A::B accessible to nested member of friend 
    }; 
}; 

Por lo tanto, debería funcionar sin ningún tipo de error.

+0

¡Gracias! Me parece autoritario. –

+0

También mire esta respuesta [http://stackoverflow.com/questions/5975421/does-friending-alass-extend-to-classes-declared-within- that-class/5975757 # 5975757). –

4

No parece haber some defect in the original standard C++03

Según C++ 03 [pre CD1] su código no debe compilar debido a que la redacción y el ejemplo dice que los miembros privados de una clase (la amistad concesión) no se puede acceder en el miembro anidado de la clase de amigo.

C++ 11 da el mismo ejemplo que en C++ 03. El único cambio realizado en ese ejemplo es que el miembro anidado (clase) de la clase de amigo puede acceder al miembro privado de la clase que otorga la amistad.

declarar una clase para ser un amigo implica que los nombres de los miembros privados y protegidos de la amistad concesión clase se puede acceder en la base especificadores y declaraciones de miembros de la clase se hizo amigo.

También se fijan en issue #45

+0

¡Ah! Gracias de nuevo. –

0

Prasoon menciona la edición # 45 ... este comportamiento cambia en C++ 0x. El comportamiento anterior fue (11,7 [class.access.nest] el párrafo 1):

Los miembros de una clase anidada no tienen acceso especial a los miembros de una clase envolvente, ni a clases o funciones que han concedido la amistad a una clase envolvente.

Esto indica claramente que gcc 4.1 es correcto según las reglas de C++ 03. gcc 4.5 y MSVC2010 están usando las reglas de C++ 0x.

Cuestiones relacionadas