2010-02-27 5 views
10

Ok, he buscado este problema y he buscado el desbordamiento de pila, pero parece que no puedo encontrar una buena respuesta. Entonces, estoy haciendo la pregunta aquí que es particular para mi problema. Si es una respuesta fácil, se agradable, soy nuevo en el lenguaje. Aquí está mi problema:Devolviendo una copia del auto de un objeto en C++

Estoy tratando de escribir un método para una clase de C++ que está sobrecargando un operador. Quiero devolver una copia de la instancia modificada, pero no la instancia en sí. Para facilitar el ejemplo, usaré una clase BigInt para demostrar el problema que estoy teniendo.

Si tuviera el siguiente código:

const BigInt & operator+() const //returns a positive of the number 
{ 
    BigInt returnValue = *this; //this is where I THINK the problem is 
    returnValue.makepositve(); //for examples sake 
    return returnValue; 
} 

me sale el error de que el valor de retorno puede haber sido creado en la pila. Sé que esto significa que tengo que crear el objeto en el montón y devolver la referencia. Pero si tuviera que cambiar la línea 3rd a algo como:

BigInt & returnValue = *this; 

me sale un error que me dice que la sintaxis no es correcta. No estoy seguro de qué hacer, ¡cualquier ayuda es muy apreciada!

Respuesta

10

El problema está en función de su firma. Realmente tiene que devolver el objeto completo y no solo una referencia.

Su función se verá así

BigInt operator+() const //returns a positive of the number 
{ 
    BigInt returnValue = *this; 
    returnValue.makepositve(); //for examples sake 
    return returnValue; 
} 
+0

ok, así que si devuelvo el objeto completo, ¿el objeto debe crearse en el montón? –

+0

No, puedes crearlo en la pila. –

+4

No, c/C++ copie el valor de retorno del marco de pila llamado al anterior. Básicamente lo que eso significa es que, cuando no tienes un puntero, el objeto se copia cuando se devuelve. (Los primitivos como punteros también se 'copian', pero no lo notarás porque apuntan al mismo objeto.) –

-1

tratar

BigInt * returnValue = this; 
+0

lo he intentado, pero el error que me dieron fue: valor inicial de referencia a no const debe ser un lvalue –

+0

'this' es un puntero, es decir,' BigInt * 'y no se puede asignar a una referencia. –

0

Mi C++ es un poco oxidado, pero ¿qué pasa:

BigInt* returnValue = new BigInt(this) 
... 
return *returnValue; 
+0

me está diciendo que ninguna instancia del constructor coincide con la lista de argumentos. –

+0

El problema con este enfoque es que terminará teniendo pérdidas de memoria. ¿Cómo va a eliminar su objeto recién creado?Además, sería un nuevo BigInt (* this) –

3

Es lo mismo que hacer que el valor de retorno del operador BigInt. A continuación, el constructor de copia va a pasar automagicamente en la declaración:

const BigInt operator+() const //returns a positive of the number 
{ 
    BigInt returnValue = *this; //this is where I THINK the problem is 
    returnValue.makepositve(); //for examples sake 
    return returnValue; 
} 

Ahora parece que un constructor de copia va a pasar dos veces, una vez en el interior del operador y otra cuando la función retorna, pero con la optimización del valor de retorno, lo hará realidad sólo suceder una vez, por lo que en cuanto a rendimiento, es lo mejor posible.

+0

En realidad es NRVO. –

0

Tenga en cuenta que los operadores sobrecargados deben tener una semántica intuitiva. Definir unario + para significar "valor absoluto", como lo hace en el código de ejemplo proporcionado, es extremadamente confuso para los clientes. Los operadores en tipos definidos por el usuario deben comportarse como en los tipos incorporados. Por ejemplo, +(-5) produce -5, no +5. Por lo tanto, la implementación de operator+ debería tener este aspecto:

BigInt& operator+() //returns the unchanged number 
{ 
    return *this; 
} 

const BigInt& operator+() const //returns the unchanged number 
{ 
    return *this; 
} 

Si desea proporcionar una función de valor absoluto, y luego hacerlo:

BigInt abs(BigInt x) 
{ 
    x.makePositive(); 
    return x; 
} 
Cuestiones relacionadas