Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: luiggy2 en 15 Octubre 2013, 01:38 am



Título: Problema operador asignación y operador asignación [struct] c++
Publicado por: luiggy2 en 15 Octubre 2013, 01:38 am
Buenas noches!

Estaba haciendo un struct que encapsulara un vector que
representa unas coordenadas en el espacio. Todo va bien hasta
que llego al operador de asignación y al operador + que no
funciona del todo bien.

El código es el siguiente y el error de compilación está debajo:

Código
  1. #ifndef _PUNTO_H_
  2. #define _PUNTO_H_
  3.  
  4. #include <vector>
  5. using namespace std;
  6.  
  7. struct Punto{
  8.  Punto(int tam){
  9.    this->_coord=vector<double>(tam,0);
  10.  }
  11.  
  12.  Punto(vector<double> v){
  13.    this->_coord=v;
  14.  }
  15.  
  16.  Punto(const Punto& p){
  17.    this->_coord=p._coord;
  18.  }
  19.  
  20.  //operadores
  21.  
  22.  Punto& operator= (const Punto& p){
  23.    Punto pp(p._coord.size()); //ERROR
  24.    pp._coord=p._coord;
  25.    return pp;
  26.  }
  27.  
  28.    Punto& operator+ (const Punto& p){
  29.      vector<double> pp = this->_coord;
  30.      for(int i=0; i<this->_coord.size(); i++){
  31. pp[i]+=p._coord[i];
  32.      }
  33.  
  34.      return Punto(pp); //ERROR
  35.    }
  36.  
  37.  
  38.  vector<double> _coord;
  39. };
  40. #endif //_PUNTO_H_
  41.  

El error que da en compilación es el siguiente:
Código:
punto.h: En la función miembro ‘Punto& Punto::operator=(const Punto&)’:
punto.h:29:11: aviso: se devolvió una referencia a la variable local ‘pp’ [activado por defecto]
punto.h: En la función miembro ‘Punto& Punto::operator+(const Punto&)’:
punto.h:40:22: error: inicialización inválida de una referencia que no es constante de tipo ‘Punto&’ desde un r-valor de tipo ‘Punto’

Donde las lineas corresponden a:
Código:
Linea 29:     Punto pp(p._coord.size());
Línea 40:      return Punto(pp);

Espero sus respuestas.
Muchas gracias!
Luiggy2


Título: Re: Problema operador asignación y operador asignación [struct] c++
Publicado por: eferion en 15 Octubre 2013, 08:38 am
Código
  1. Punto& operator= (const Punto& p);
  2.  
  3. Punto& operator+ (const Punto& p);

Fíjate que en las dos declaraciones, el valor de retorno es una referencia.

No puedes devolver como referencia una variable o clase cuyo ámbito sea la función que define el operador. Me explico:

Código
  1. int& GetValor( )
  2. {
  3.  int i;
  4.  i=5;
  5.  return i;
  6. }
  7.  
  8. void main( )
  9. {
  10.  int valor = GetValor( );
  11. }

Aquí se reproduce el mismo problema. El ámbito de "i" es GetValor... fuera de dicha función, "i" no tiene ni sentido ni valor. Si devuelves una referencia a "i"... y después "i" se libera, cualquier lectura y/o escritura sobre la referencia será, cuanto menos, insegura. Lo mejor que te puede pasar en estos casos es que o bien te falle al compilar o bien se caiga la aplicación.

Además, el operador= tiene un problema. Si tu sobrecargas el operador de asignación se presupone que quieres modificar la instancia actual de la clase... y tu ahí estás haciendo una copia de p para devolverla y sin modificar "this"... eso no tiene sentido.

el operador de asignación debería tener más bien esta forma:

Código
  1. Punto& operator= (const Punto& p)
  2. {
  3.    _coord = p._coord;
  4.    return *this;
  5. }

Ahora fíjate que en el return, en vez de devolver una referencia a una clase propia de la función, estoy devolviendo una referencia a la instancia de la clase "modificada", que sí existirá después del return.

En cuanto al operador suma, lo mejor es que no devuelvas una referencia.

Un saludo.


Título: Re: Problema operador asignación y operador asignación [struct] c++
Publicado por: luiggy2 en 16 Octubre 2013, 23:35 pm
Perfecto, no se como no me di cuenta!
Esto de programar con sueño no es muy bueno.

Muchas gracias!
Luiggy2