Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: _Enko en 5 Febrero 2015, 15:43 pm



Título: Sobrecarga operador +
Publicado por: _Enko en 5 Febrero 2015, 15:43 pm
Hola, estoy practicando el tema de sobrecarga y me tope con 2 problemas. :silbar:

Código
  1. class Foo
  2. {
  3. public:
  4. //Foo& operator+(const Foo& f); tampoco funciona
  5. //Si funciona (Foo& f)
  6. Foo& operator+(Foo const& f){
  7. bar_ += f.getBar();
  8. return *this;
  9. }
  10. int getBar(){
  11. return bar_;
  12. }
  13. private:
  14. int bar_;
  15. };
  16.  
Por alguna razon, cuando sobrecargo el operador +, Visual Studio 2010 me exigue que el parametro sea una referencia simple "Foo& f" y no const. Si coloco const, salta error que no puede convertir de const & a & desde el metodo Foo::getBar().
No tengo visual studio a mano como pasar el error exacto.
(passing `const Foo' as `this' argument of `int Foo::getBar()' discards qualifiers )

Otra cosa, en http://www.parashift.com/c++-faq/overview-op-ov.html
Coloca este ejemplo
Código:
  Fred operator+ (Fred const& x, Fred const& y);
Pero vc++ y blodshed dev c++ tambien se quejan de que solo se puede pasar un argumento a un operador unario.

Será que tiene solamente parcial soporte de c++11?

Saludos y Gracias


Título: Re: Sobrecarga operador +
Publicado por: eferion en 5 Febrero 2015, 15:55 pm
getbar no es const, no puedes llamar a un método "no const" desde una referencia "const".

Por otro lado, el otro ejemplo que has puesto:

Código
  1. Fred operator+ (Fred const& x, Fred const& y);

Este ejemplo únicamente compila si el operador se sobrecarga fuera de la clase "Fred". Eso sí, para asegurar un funcionamiento óptimo lo suyo es hacer que este método sea "friend" de la clase "Fred".


Título: Re: Sobrecarga operador +
Publicado por: _Enko en 5 Febrero 2015, 17:58 pm
Muchas gracias :)

Tiene sentido si se toma "Foo const& f" como referencia a Foo constante, all llamar a  algun metodo de f, es posible que este modifique el objeto.

Entonces, "const Foo& f" es lo mismo que "Foo const&  f"?

Hay alguna manera de hacer "constante referencia  a Foo" y no "referencia a Foo constante"?

Me refiero a :
Código
  1. void f(foo "referencia constante a" f){
  2.        f = foo(); //error, f referenciaria otro objeto
  3.        f.set(valor); //ok, f sigue referenciando a f pero con un miembro cambiado de valor.
  4. }
  5.  

Es decir, que se pueda cambiar los miembros de la referencia, pero no la referencia.

PD, creo que correctamente seria asi el la sobrecarga de +?
Código
  1. Foo operator+(const Foo& f)
  2. {
  3.        Foo b;
  4. b.bar_ = this->bar_ + f.bar_;
  5. return b;
  6. }
  7.  

Y tambien, + tendria que devolver objeto  nuevo mientras que += referencia al objeto?
Código
  1. Foo operator+(const Foo& f);
  2. Foo& operator+=(Foo const& f);
  3.  


Saludos y Gracias.


Título: Re: Sobrecarga operador +
Publicado por: eferion en 6 Febrero 2015, 08:04 am
Entonces, "const Foo& f" es lo mismo que "Foo const&  f"?

Es lo mismo sí.

Hay alguna manera de hacer "constante referencia  a Foo" y no "referencia a Foo constante"?

Foo& variable -> "constante referencia a Foo"
const Foo& variable -> "referencia a Foo constante"

Cuando declaras una referencia, el compilador te obliga a darle un valor en ese mismo momento. Despuées de la inicialización, verás que no vas a poder modificar la referencia. Es decir, el enlace de referencia es constante siempre. Debido a esto, el modificador "const" únicamente tiene sentido si amplía la cobertura... y de la única forma en la que puede hacer esto es haciendo que la clase o variable sea de solo lectura.

PD, creo que correctamente seria asi el la sobrecarga de +?
Código
  1. Foo operator+(const Foo& f)
  2. {
  3.        Foo b;
  4. b.bar_ = this->bar_ + f.bar_;
  5. return b;
  6. }
  7.  

Es una forma de implementarlo... ahora, si Foo tiene un constructor que permite inicializar "bar_", es un poco más eficiente llamar a dicho constructor:

Código
  1. Foo operator+(const Foo& f) const
  2. {
  3.        return Foo{ bar_ + f.bar_ };
  4. }

Por cierto, nota el "const" de la función... los operadores que no tienen el igual no deberían modificar la instancia actual y deberían, por tanto, ser "const". Puede parecer una tontería, pero ya has visto que si un miembro no tiene el modificador "const" no puedes usarlo en una función "const".

Y tambien, + tendria que devolver objeto  nuevo mientras que += referencia al objeto?

A ver, el operador "+" tiene que devolver un objeto nuevo porque, como te he comentado antes, este operador no debe modificar la instancia actual. Crear un objeto nuevo responde a la necesidad de devolver el resultado en un objeto que no sea el actual.

El operador "+=" si que tiene que modificar la instancia actual y, dado que al finalizar la función la instancia actual tendrá el valor bueno, suele ser más eficiente devolver una referencia que crear un objeto nuevo basado en el valor actual.

Espero haberte resuelto las dudas.

Un saludo.


Título: Re: Sobrecarga operador +
Publicado por: _Enko en 6 Febrero 2015, 14:56 pm
Muchas gracias eferion :D

Me has sacado un monton de dudas y puntos de foco debiles  ;-)


Gracias nuevamente :)

Y pueden dar por cerrado el tema ^^