Problema operador asignación y operador asignación [struct] c++

Iniciado por luiggy2, 15 Octubre 2013, 01:38 AM

0 Miembros y 1 Visitante están viendo este tema.

luiggy2

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 (cpp) [Seleccionar]

#ifndef _PUNTO_H_
#define _PUNTO_H_

#include <vector>
using namespace std;

struct Punto{
  Punto(int tam){
    this->_coord=vector<double>(tam,0);
  }

  Punto(vector<double> v){
    this->_coord=v;
  }
 
  Punto(const Punto& p){
    this->_coord=p._coord;
  }
 
  //operadores

  Punto& operator= (const Punto& p){
    Punto pp(p._coord.size()); //ERROR
    pp._coord=p._coord;
    return pp;
  }
   
    Punto& operator+ (const Punto& p){
      vector<double> pp = this->_coord;
      for(int i=0; i<this->_coord.size(); i++){
pp[i]+=p._coord[i];
      }
     
      return Punto(pp); //ERROR
    }
 
 
  vector<double> _coord;
};
#endif //_PUNTO_H_


El error que da en compilación es el siguiente:
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:

Linea 29:     Punto pp(p._coord.size());
Línea 40:      return Punto(pp);


Espero sus respuestas.
Muchas gracias!
Luiggy2
" Las grandes ideas suelen salir la mayoría de veces de grandes estupideces "

eferion

Código (cpp) [Seleccionar]

Punto& operator= (const Punto& p);

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 (cpp) [Seleccionar]

int& GetValor( )
{
  int i;
  i=5;
  return i;
}

void main( )
{
  int valor = GetValor( );
}


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 (cpp) [Seleccionar]

Punto& operator= (const Punto& p)
{
    _coord = p._coord;
    return *this;
}


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.

luiggy2

Perfecto, no se como no me di cuenta!
Esto de programar con sueño no es muy bueno.

Muchas gracias!
Luiggy2
" Las grandes ideas suelen salir la mayoría de veces de grandes estupideces "