elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Funciones Friends y Namespaces..
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Funciones Friends y Namespaces..  (Leído 655 veces)
digimikeh

Desconectado Desconectado

Mensajes: 184


Ver Perfil
Funciones Friends y Namespaces..
« en: 1 Marzo 2019, 00:16 am »

Hola!

Me parece extraño que tenga que definir una función friend anteponiendo el espacio de nombre si se supone que lo dejé estipulado al principio:

Código
  1. //Persona.h
  2.  
  3. namespace Agenda{
  4.   class Persona{
  5.  
  6.      int edad;
  7.      friend int f_obtenerEdad();
  8.  
  9.   };
  10. }
  11.  

Código
  1. //Persona.cpp
  2. #include "Persona.h"
  3. using namespace Agenda;
  4.  
  5. int f_obtenerEdad(Persona & _p){
  6.   return _p.edad;          //Error, edad es privado
  7. }
  8.  


En cambio, si lo hago asi:
Código
  1. //Persona.cpp
  2. #include "Persona.h"
  3. using namespace Agenda;
  4.  
  5. int Agenda::f_obtenerEdad(Persona & _p){
  6.   return _p.edad;         //Esto lo asimila correctamente
  7. }
  8.  


Tenía entendido que si yo escribía "using namespace X", no era necesario llamar a los miembros de un objeto usando X:: , pero en este caso del friend no se cumple, por qué será?

Gracias..


« Última modificación: 1 Marzo 2019, 00:19 am por digimikeh » En línea

Dungeons & dragons;
dragons.Attack();
K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 904



Ver Perfil
Re: Funciones Friends y Namespaces..
« Respuesta #1 en: 1 Marzo 2019, 00:40 am »

Esto es porque estás declarando el prototipo de la función <f_obtenerEdad()> dentro del <namespace Agenda> pero la implementación de la función lo estás haciendo fuera; lo que sea hace confuso.

Para que funcione correctamente debes hacer que tanto el prototipo como la implementación pertenezcan al <namespace Agenda>.
Código
  1. namespace Agenda{
  2.    class Persona{
  3.        int edad;
  4.        public:
  5.            friend int f_obtenerEdad(const Persona&);
  6.    };
  7.  
  8.    int f_obtenerEdad(const Persona &p){
  9.        return p.edad;
  10.    }
  11. }

Al hacerlo en ficheros separados debes especificar que la implementación también pertenece al <namespace Agenda> por eso que tienes que ponerlo para que funcione.
Puedes leer un poco más al respecto AQUÍ :-X


En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
digimikeh

Desconectado Desconectado

Mensajes: 184


Ver Perfil
Re: Funciones Friends y Namespaces..
« Respuesta #2 en: 1 Marzo 2019, 01:21 am »

Pero por lo visto esto solo sucede con las funciones amigas verdad?
En línea

Dungeons & dragons;
dragons.Attack();
K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 904



Ver Perfil
Re: Funciones Friends y Namespaces..
« Respuesta #3 en: 1 Marzo 2019, 01:44 am »

No, he probado a crear una función simple para probar y te dejaré por aquí el código y las salidas que genera.

Código
  1. #include <iostream>
  2.  
  3. namespace Agenda{
  4. class Persona{
  5. public:
  6. int a;
  7. Persona():a(5){}
  8. };
  9. int f(const Persona&);
  10. }
  11.  
  12. using namespace Agenda;
  13.  
  14. int main(){
  15. Persona p1;
  16. std::cout << f(p1) << std::endl;
  17. }
  18.  
  19. int f(const Persona &p){
  20. return p.a;
  21. }

La salida para este caso es un error de compilación:
Código:
En la función `main':
test.cpp:(.text+0x2b): referencia a `Agenda::f(Agenda::Persona const&)' sin definir
collect2: error: ld returned 1 exit status

Este error se puede solucionar añadiendo el <namespace Agenda> a la implementación de la función tal que:
Código
  1. int Agenda::f(const Agenda::Persona &p){
  2.    return p.a;
  3. }



En cambio, si ponemos la función dentro del <namespace>...
Código
  1. #include <iostream>
  2.  
  3. namespace Agenda{
  4. class Persona{
  5. public:
  6. int a;
  7. Persona():a(5){}
  8. };
  9.  
  10. int f(const Persona &p){
  11. return p.a;
  12. }
  13. }
  14.  
  15. using namespace Agenda;
  16.  
  17. int main(){
  18. Persona p1;
  19. std::cout << f(p1) << std::endl;
  20. }

La salida en este caso sí es la correcta:
Código:
Salida: 5
En línea

Código
  1. cout << "Todos tenemos un defecto, un error en nuestro código" << endl;
digimikeh

Desconectado Desconectado

Mensajes: 184


Ver Perfil
Re: Funciones Friends y Namespaces..
« Respuesta #4 en: 1 Marzo 2019, 02:33 am »

Ok, pero ahí estas declarando una funcion fuera de la clase, yo decía lo de friend porque se declara dentro de la clase, aunque no sea miembro.
En línea

Dungeons & dragons;
dragons.Attack();
Loretz

Desconectado Desconectado

Mensajes: 112


Ver Perfil
Re: Funciones Friends y Namespaces..
« Respuesta #5 en: 1 Marzo 2019, 05:03 am »

En tu ejemplo, la declaración de f_obtenerEdad() y su definición son distintas (en otros bares podrían decirte que es más respetuoso poner ejemplos que compilen).

Yo veo dos cosas, una es que las formas habituales de definir una función friend son
1) "inline", directamente en el cuerpo de la clase, y
2) en un archivo cpp, ampliando el mismo namespace. (Abajo pongo esta alternativa).

La otra es que puedes tener dos funciones (sobrecarga) con la misma firma, una friend en el mismo namespace de la clase, y otra no friend y global, y en este caso con using namespace... el compilador no sabría a cuál de las dos te refieres.

Acá abajo va un ejemplo:

Código
  1. // en Agenda.h
  2. namespace Agenda {
  3.    class Persona {
  4.        int edad = 42;
  5.        friend int f_obtenerEdad(Persona& _p);
  6.  
  7.    public:
  8.        int sumaEdad(int i)
  9.        {
  10.            return edad + i;
  11.        }
  12.    };
  13. }
  14.  
  15. // Mejor que la de abajo
  16. // en Agenda.cpp
  17. namespace Agenda {
  18.    int f_obtenerEdad(Persona& p)
  19.    {
  20.        return p.edad;
  21.    }
  22. }
  23.  
  24. /*
  25. // Menos mejor que la de arriba
  26. int Agenda::f_obtenerEdad(Agenda::Persona& _p)
  27. {
  28.     return _p.edad;
  29. }
  30. */
  31.  
  32.  
  33. // otra pero global:
  34. int f_obtenerEdad(Agenda::Persona& _p)
  35. {
  36.    return _p.sumaEdad(5);
  37. }
  38.  
  39.  
  40.  
  41.  
  42. #include <iostream>
  43.  
  44. int main()
  45. {
  46.    Agenda::Persona p;
  47.    std::cout << Agenda::f_obtenerEdad(p) << '\n';
  48.  
  49.    std::cout << ::f_obtenerEdad(p) << '\n'; // usa la versión global
  50. }
En línea

digimikeh

Desconectado Desconectado

Mensajes: 184


Ver Perfil
Re: Funciones Friends y Namespaces..
« Respuesta #6 en: 2 Marzo 2019, 02:14 am »

Me queda claro, gracias a ambos.. :rolleyes:
En línea

Dungeons & dragons;
dragons.Attack();
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Bug Steam Friends
Juegos y Consolas
SmopuiM 0 505 Último mensaje 21 Julio 2006, 09:28 am
por SmopuiM
Duda namespaces en XML
Desarrollo Web
xexio 0 636 Último mensaje 23 Agosto 2012, 16:41 pm
por xexio
Guia de Namespaces y Assemblys completa?
.NET (C#, VB.NET, ASP)
Vaagish 2 1,587 Último mensaje 25 Febrero 2014, 21:24 pm
por Vaagish
Problema con C++/CLI: no encuentra namespaces [SOLUCIONADO]
.NET (C#, VB.NET, ASP)
SARGE553413 2 1,135 Último mensaje 4 Julio 2014, 16:27 pm
por SARGE553413
MOVIDO: Problema con C++/CLI: no encuentra namespaces
Programación C/C++
Eternal Idol 0 607 Último mensaje 3 Julio 2014, 13:16 pm
por Eternal Idol
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines