friendship and inheritance c++
Accede a la funciĆ³n de amigo definida en clase (2)
Hay tal código:
#include <iostream>
class A{
public:
friend void fun(A a){std::cout << "Im here" << std::endl;}
friend void fun2(){ std::cout << "Im here2" << std::endl; }
friend void fun3();
};
void fun3(){
std::cout << "Im here3" << std::endl;
}
int main()
{
fun(A()); // works ok
//fun2(); error: ''fun2'' was not declared in this scope
//A::fun2(); error: ''fun2'' is not a member of ''A''
fun3(); // works ok
}
Cómo acceder a la función fun2 ()?
La razón por la que puede llamar a la fun
es que la declaración de amigo dentro de la clase A
hace visible solo mediante búsqueda dependiente de argumentos. De lo contrario, las declaraciones de amigos no hacen que las funciones que declaran sean automáticamente visibles fuera del alcance de la clase donde aparecen.
Debes agregar una declaración en el ámbito del espacio de nombres o dentro de main
para hacer que fun2
visible en main
.
P.ej
void fun2();
fun3
es visible dentro de main
porque su definición (fuera de la clase) también es una declaración que lo hace visible desde main
.
ISO / IEC 14882: 2011 7.3.1.2:
El nombre del amigo no se encuentra mediante búsqueda no calificada (3.4.1) o por búsqueda calificada (3.4.3) hasta que se proporcione una declaración coincidente en ese ámbito de espacio de nombres (ya sea antes o después de la definición de clase que otorga amistad).
3.4.2 (búsqueda de nombre dependiente del argumento) / 4:
Todas las funciones de amigo de ámbito de nombre de nombre o plantillas de función de amigo declaradas en clases asociadas son visibles dentro de sus respectivos espacios de nombres, incluso si no son visibles durante una búsqueda ordinaria (11.3).
class A{
public:
friend void fun(A a){std::cout << "Im here" << std::endl;}
friend void fun2(){ std::cout << "Im here2" << std::endl; }
friend void fun3();
};
Aunque su definición de fun2
define una función "global" en lugar de un miembro, y la convierte en friend
de A
al mismo tiempo, aún le falta una declaración de la misma función en el alcance global.
Eso significa que ningún código en ese alcance tiene idea de que fun2
existe.
El mismo problema ocurre por fun
, excepto que Argument-Dependent Lookup puede hacerse cargo y encontrar la función, porque hay un argumento de tipo A
Recomiendo en cambio definir tus funciones de la manera habitual:
class A {
friend void fun(A a);
friend void fun2();
friend void fun3();
};
void fun(A a) { std::cout << "I''m here" << std::endl; }
void fun2() { std::cout << "I''m here2" << std::endl; }
void fun3();
Fíjate ahora que todo funciona (excepto fun3
porque nunca lo fun3
).