2012-06-07 9 views
6

tengo dos dudas acerca de este código de abajo:funciones friend de una clase dentro de un espacio de nombres

namespace A { class window; } 

void f(A::window); 

namespace A 
{ 
    class window 
    { 
    private: 
     int a; 
     friend void ::f(window); 
    }; 
} 

void f(A::window rhs) 
{ 
    std::cout << rhs.a << std::endl; 
} 

1) ¿por qué necesito para calificar la función miembro f dentro de la clase de ventana que ser global haciendo :: f (ventana)?

2) ¿Por qué necesito predecir la función f (A :: ventana) en este caso particular, mientras que cuando la clase no está definida dentro de un espacio de nombres está bien para la función declarada después de declarar la función amigo.

+0

Aquí hay una explicación rápida sobre qué clases son amigables http://www.cplusplus.com/doc/tutorial/inheritance/ –

+0

@Hans lo siento, pero esto está fuera de mi pregunta – AlexDan

+1

@Hans, por favor, por favor, no enlace cplusplus.com - http://programmers.stackexchange.com/q/88241/36523 – Griwes

Respuesta

4

Cuando declara f() como amigo, en realidad se hace en el espacio de nombres adjunto de la clase contenedora (A en este caso) si una declaración directa no está presente todavía.

Así que este ...

namespace A 
{ 
    class window 
    { 
    private: 
     friend void ::f(window); 
    }; 
} 

se convierte esencialmente en esto ...

namespace A 
{ 
    class window; 
    void f(window); 

    class window 
    { 
    private: 
     friend void f(window); 
    }; 
} 

Editar: Aquí hay un fragmento del C++ estándar que explicltly habla de este escenario:

Standard 7.3.1.2/3:

Todos los nombres declarados por primera vez en un espacio de nombres son miembros de ese espacio de nombres. Si una declaración de amigo en una clase no local primero declara una clase o función, la clase o función amiga es un miembro del espacio de nombres más interno. El nombre del amigo que no se encuentra en las operaciones de búsqueda no calificado (3.4.1) o mediante operaciones de búsqueda cualificado (3.4.3) hasta que una declaración coincidente se proporciona en ese ámbito espacio de nombres (ya sea antes o después de la definición de clase amistad concesión).

+0

por lo tanto, por el ejemplo anterior, f (ventana) se trata un miembro de espacio de nombres a? –

+0

@VishnuPedireddi Sí. –

+0

¿Qué sucede si f (ventana) está definida en un espacio de nombre de su propio espacio de nombres B? ¿F (ventana) pertenecería al espacio de nombres A y al espacio de nombres B? –

3

En cuanto a 1), su función no está en el espacio de nombres, por lo que debe usar :: para indicar al compilador que lo busque fuera del espacio de nombres.

De lo contrario, sólo se buscará la función dentro del espacio de nombres (por eso es que existen). La búsqueda Koenig no se aplica aquí, ya que la clase ventana está dentro del espacio de nombres.

no muy seguro sobre 2), sin embargo, pero apuesto a que está relacionada con 1).

1

1) porque la función f se declara y define fuera del espacio de nombre actual. Si movió la definición de su clase al mismo espacio de nombres que la función ya sea global o de lo contrario no sería necesario.

2) siempre hay que declarar una función antes de que se hace referencia. Tu clase hace referencia a la función con la declaración de amigo.

+0

¿qué quieres decir con refrences? ¿Qué pasa cuando la clase no dentro de un namaespacio no es el mismo caso aquí? – AlexDan

+0

Necesita poder ver que la función existe. Si la clase está en el mismo espacio de nombres que la definición de la función, puede encontrarla, pero el orden de la declaración es importante. Esta es también la razón por la cual la definición de su función debe venir después de la declaración de clase, ya que usa un miembro de esa clase. – AJG85

+0

Con respecto a (2), vea la respuesta de CaptainObvlious - hay una sutil. AlexDan no está del todo correcto aquí. A veces, una declaración de amigo no necesita hacer referencia a una función declarada previamente; en su lugar, la declaración de amigo en sí cuenta como la declaración oficial de la función, y la función se puede definir más adelante. Ver la respuesta de CaptainObvlious. –

Cuestiones relacionadas