[C con Clase] Destrucción automática de objetos temporales

Salvador Pozo salvapozo en gmail.com
Dom Dic 7 20:48:07 CET 2008


Hola:

> Sí, yo también he comprobado que el compilador (g++, en mi caso) hace cosas distintas y no siempre usa la asignación y el constructor copia sobrecargados. Imagino que, ejecutar un return desde un método que devuelve claseX, en muchos casos copia los datos miembros del objeto y eventual tabla virtual y lo mete en el pila de vuelta al código que ha llamado al método, en lugar de usar asignación o constructor copia.

Eso depende, en cierta medida, del compilador y del sistema operativo.

> Lo que sí no acabo de tener claro es con que criterio decidir si un método u operador sobrecargado ha de devolver claseX o claseX&. Porque he visto que en ambos casos puedo hacer cosas similares con lo que he devuelto:
>
> (a+b).visualizar()
>
> por ejemplo. ¿Tenéis alguna sugerencia al respecto?

No es lo mismo retornar un objeto por valor que hacerlo por
referencia. En el segundo caso no siembre funcionará. He escrito un
ejemplo que no funciona cuando se define el valor de retorno del
operador + como una referencia:

----8<------
#include <iostream>

using namespace std;

class Numero {
    public:
       Numero(int xi=0) : x(xi) { cout << "Constructor (" << x << ")" << endl; }
       Numero(const Numero &n) : x(n.x) { cout << "Constructor copia
(" << x << ")" << endl; }
       Numero &operator+(const Numero &n);
       void Ver() { cout << "Numero = " << x << endl; }
    private:
       int x;
};

Numero &Numero::operator+(const Numero &n) {
    Numero temp;

    temp.x = x+n.x;
    return temp;
}

int main()
{
    Numero a(10), b(20);

    (a+b).Ver();
    return 0;
}
----8<------

En este caso no sólo obtenemos un aviso del compilador, indicando que
estamos devolviendo una referencia a un objeto local:
otrapru.cpp: In member function `Numero& Numero::operator+(const Numero&)':
otrapru.cpp:16: warning: reference to local variable `temp' returned

Sino que, además, el cálculo no es correcto, ya que el valor mostrado es cero:
Constructor (10) <- a
Constructor (20) <- b
Constructor (0)  <- creación de temp
Numero = 0

Si no usamos referencias, este ejemplo funciona correctamente.

En el caso del operador de asignación, la declaración debe ser
obligatoriamente, para este ejemplo:

Numero &Numero::operator=(const Numero &n);

Hasta pronto.
-- 
Salvador Pozo Coronado
http://www.conclase.net
mailto:salvapozo en gmail.com




Más información sobre la lista de distribución Cconclase