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)
| | |-+  Sobrecarga de operador << solo me compila si uso la palabra "friend"
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Sobrecarga de operador << solo me compila si uso la palabra "friend"  (Leído 1,791 veces)
digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Sobrecarga de operador << solo me compila si uso la palabra "friend"
« en: 13 Febrero 2019, 04:44 am »

Buenas amigos..

Tenía entendido que la palabra reservada "friend" permitía acceder a todas mis variables privadas de mi clase desde fuera, es como una excepción a la regla, para friend sería todo publico.

He querido utilizar el operador sobrecargado << para que mi clase pueda ser impresa por la salida estándar.

Esto es lo que tengo:

Código
  1. //Persona.h
  2. #include <iostream>
  3.  
  4. class Persona{
  5.  
  6.     char * nombre;
  7.     int edad;
  8.  
  9. public:
  10.  
  11.     Persona();
  12.     ~Persona();
  13.  
  14.     //La siguiente linea da error si no coloco la palabra friend al principio
  15.     std::ostream & operator<<(std::ostream & os, Persona & _estaPersona);
  16.     char * LeerNombre() const;
  17.     int LeerEdad() const;
  18.     void InsertarNombre(const char * _nuevoNombre);
  19.     void InsertarEdad(const int _nuevaEdad);
  20.  
  21. };
  22.  


Código
  1. //Persona.cpp
  2.  
  3. #include "Persona.h"
  4.  
  5. using namespace std;
  6.  
  7. //Sobrecarga operador
  8. ostring & operator<<(ostring & os, const Persona & _estaPersona){
  9.     os << "Nombre : " << _estaPersona.LeerNombre() << endl;
  10.     os << "Edad     : " << _estaPersona.LeerEdad() << endl;
  11.     return os;
  12. }
  13.  
  14. char * Persona::LeerNombre(){
  15.     return nombre;
  16. }
  17.  
  18. int Persona::LeerEdad(){
  19.     return edad;
  20. }
  21.  
  22. void Persona::InsertarNombre(const char * _nuevoNombre){
  23.     strcpy(nombre, _nuevoNombre);
  24. }
  25.  
  26. void Persona::InsertarEdad(const int _nuevaEdad){
  27.     edad = _nuevaEdad;
  28. }
  29.  
  30.  

Código
  1. //main.cpp
  2. #include Persona.h
  3.  
  4. int main (){
  5.     Persona p;
  6.     p.InsertarNombre("ElHacker");
  7.     p.Edad(37);
  8.  
  9.     std::cout << p << endl;
  10. }
  11.  

Lo que no entiendo, es que según la definición de friend, esto no me calza, yo no quiero acceder desde fuera a una propiedad privada, solo estoy intentando acceder a LeerNombre() y LeerEdad() que son publicas, no debería necesitar colocar friend... es que acaso friend con el operador trabaja de forma distinta?

Gracias de antemano.


En línea

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

Mensajes: 1.008



Ver Perfil
Re: Sobrecarga de operador << solo me compila si uso la palabra "friend"
« Respuesta #1 en: 13 Febrero 2019, 05:02 am »

Este es un error típico con la sobrecarga tanto del operador << como del operador >>.
Ambas sobrecargas son funciones, no métodos. Un método de una clase puede acceder a los miembros privados por si sólo porque en eso consiste un método, en una función que pertenece a una clase.

Sin embargo, esa sobrecarga es una función, no un método. Entonces el prototipo de la función debe definirse fuera de la clase. Y la implementación de la función si se hace en un fichero distinto se hace sin referenciar la clase a la que pertenece (ya que no pertenece a ninguna).

Y cuando queremos hacer que una función sea "friend" entonces el prototipo lo incluimos dentro de la clase precedido de la palabra <friend> pero si no se usa la palabra <friend> entonces hay que declararlo fuera de la clase.

Código
  1. class MiClase{
  2.    private:
  3.        // miembros y metodos privados
  4.    public:
  5.        // miembros y metodos publicos
  6.        // Opcion 1: sobrecarga con friend
  7.        friend std::ostream& operator<<(ostream&, const MiClase&);
  8. };
  9. // Opcion 2: sobrecarga sin friend
  10. std::ostream& operator<<(ostream&, const MiClase&);

Espero haber resuelto tus dudas respecto a este tema. Suerte :-X

PD: He visto un extraño <ostring> en tu código... :silbar:


En línea

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

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Sobrecarga de operador << solo me compila si uso la palabra "friend"
« Respuesta #2 en: 13 Febrero 2019, 13:38 pm »

entnoces no era obligación meter la palabra "friend", sabía!.. no me hacía sentido, simplemente tenía que declarar y definir fuera de la clase esta sobrecarga ....

He usado también la sobrecarga == y ésta sí que se comporta como yo esperaba dentro de la clase, por lo visto no todos los operadores se sobrecargan de la misma forma verdad?.

Estuve observando el ostream que mencionas, pero por mas que veo, se me pasa el error, no lo veo, en qué linea está ?..

Saludos y gracias.
En línea

Dungeons & dragons;
dragons.Attack();
CalgaryCorpus


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: Sobrecarga de operador << solo me compila si uso la palabra "friend"
« Respuesta #3 en: 13 Febrero 2019, 15:54 pm »

Para los operadores, considera el tipo que esta a la izquierda del operador. Son distintos cuando usas << y cuando usas ==

ostream << clase

clase == clase

Donde defines la funcion o metodo, depende del tipo de la izquierda del operador.

El primero de ellos se define fuera de la clase, el segundo dentro de la misma.

Los metodos al interior de la clase no necesitan especificar el operando de la izquierda del operador, pues se sobreentiende que se trata del objeto donde se ejecuta el metodo. Solo requieren especificar 1 parametro, el de la derecha del operador.

Cuando pones la firma de la funcion dentro de la clase, sin poner friend, el compilador te va reclamar no porque no pusiste "friend", te va a reclamar porque al ponerla dentro de la clase, es un metodo como el resto y el operator<< solo puede recibir 1 parametro y le estas pasando 2.

En línea

Aqui mi perfil en LinkedIn, invitame un cafe aqui
K-YreX
Moderador
***
Desconectado Desconectado

Mensajes: 1.008



Ver Perfil
Re: Sobrecarga de operador << solo me compila si uso la palabra "friend"
« Respuesta #4 en: 13 Febrero 2019, 18:51 pm »

Estuve observando el ostream que mencionas, pero por mas que veo, se me pasa el error, no lo veo, en qué linea está ?..

En tu fichero Persona.cpp en la declaración de la sobrecarga del operador <<. Y si lo quieres ver en el primer mensaje de este tema, el segundo bloque de código:
Código
  1. //Persona.cpp
  2.  
  3. #include "Persona.h"
  4.  
  5. using namespace std;
  6.  
  7. //Sobrecarga operador
  8. ostring & operator<<(ostring & os, const Persona & _estaPersona){
  9.     os << "Nombre : " << _estaPersona.LeerNombre() << endl;
  10.     os << "Edad     : " << _estaPersona.LeerEdad() << endl;
  11.     return os;
  12. }
  13.  
En línea

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

Desconectado Desconectado

Mensajes: 117


Ver Perfil
Re: Sobrecarga de operador << solo me compila si uso la palabra "friend"
« Respuesta #5 en: 13 Febrero 2019, 22:53 pm »

La sobrecarga del operador << suele hacerse de dos maneras (típicamente); si necesita acceder a miembros privados o protegidos de la clase, será una función friend; si no lo necesita, se prefiere una función libre. (Más, te diría que siempre que existe la alternativa, se prefieren funciones libres a funciones miembro).

No quisiera entrar en controversias personales, pero... sobre la afirmación de YreX-DwX:
Citar
Ambas sobrecargas son funciones, no métodos.

Es muy frecuente usar la palabra "método" para referirse a funciones miembro de alguna clase, pero que sea un uso común no quiere decir que sea la forma correcta, y menos que sea obligatorio. El estándar C++ las llama "member function", y los que no hablamos inglés, por comodidad les decimos "funciones miembro", claro que también alguien puede decirles "procedimientos", "métodos", o cosas así, pero es sólo por comodidad, no porque así deba decirse. (Prueba: ponte a buscar las distintas ocurrencias de la palabra "method" en el documento del estándar y verás que en ningún caso se aplica a funciones, a ningún tipo).

Por otro lado:
Código:
void Persona::InsertarNombre(const char * _nuevoNombre){
     strcpy(nombre, _nuevoNombre);
}
Aquí tienes un problema, "nombre" no tiene memoria asignada (con new, por ejemplo), es un puntero que apunta a quién sabe donde, de modo que lo esperable es que strcpy haga un destrozo.

En línea

digimikeh

Desconectado Desconectado

Mensajes: 191


Ver Perfil
Re: Sobrecarga de operador << solo me compila si uso la palabra "friend"
« Respuesta #6 en: 14 Febrero 2019, 21:50 pm »

Si, @Loretz , lo que esperaria ahí es Segment fault 11... tienes razon, aunque lo escribi a la rapida para mostrar mi problema de ostream mas que nada...  :laugh:

@Yrex-DwX ya me di cuenta que con ostring no sacaba nada jajha
En línea

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

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines