2010-02-27 13 views
10

Ok, quindi ho cercato su Google questo problema e ho cercato lo stack overflow ma non riesco a trovare una buona risposta. Quindi, sto facendo la domanda qui che è particolare al mio problema. Se è una risposta facile, per favore sii gentile, sono nuovo della lingua. Ecco il mio problema:Restituzione di una copia di un oggetto in C++

Sto provando a scrivere un metodo per una classe C++ che sta sovraccaricando un operatore. Voglio restituire una copia dell'istanza modificata ma non l'istanza stessa. Per semplicità di esempio, userò una classe BigInt per dimostrare il problema che sto avendo.

Se ho avuto il seguente codice:

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; 
} 

ottengo l'errore che il valore di ritorno potrebbe essere stato creato in pila. So che questo significa che devo creare l'oggetto sull'heap e restituire il riferimento. Ma se dovessi cambiare la 3 ° linea a qualcosa di simile:

BigInt & returnValue = *this; 

ottengo un errore che mi diceva che la sintassi non è giusto. Non sono sicuro di cosa fare, qualsiasi aiuto è molto apprezzato!

risposta

10

Il problema è nella tua firma funzione. Devi davvero restituire l'intero oggetto e non solo un riferimento.

La funzione sarà simile a questa

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

ok, quindi se restituisco l'intero oggetto, l'oggetto deve essere creato sull'heap? –

+0

No, puoi crearlo in pila. –

+4

No, c/C++ copia il valore di ritorno dal frame dello stack chiamato a quello precedente. Fondamentalmente ciò significa che, quando non si dispone di un puntatore, l'oggetto viene copiato quando viene restituito. (Anche i primitivi come i puntatori vengono "copiati", ma non li noterai perché puntano semplicemente allo stesso oggetto.) –

-1

provare

BigInt * returnValue = this; 
+0

Ci ho provato, ma l'errore che ho ottenuto è stato: il valore iniziale di riferimento a non-const deve essere un lvalue –

+0

"questo" è un puntatore, ad esempio "BigInt *" e non può essere assegnato a un riferimento. –

0

mio C++ è un po 'arrugginito, ma per quanto riguarda:

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

mi sta dicendo che nessuna istanza del costruttore corrisponde alla lista degli argomenti. –

+0

Il problema con questo approccio è che si finirà per perdere memoria. Come cancellerai il tuo oggetto appena creato?Inoltre, sarebbe nuovo BigInt (* this) –

3

Si potrebbe anche fare il valore di ritorno dell'operatore BigInt. Poi il costruttore di copia avverrà automagicamente sul ritorno:

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; 
} 

Ora sembra un costruttore di copia avverrà due volte, una volta dentro l'operatore e l'altro quando la funzione ritorna, ma con Return Value Optimization, sarà in realtà solo capita una volta, quindi le prestazioni sono migliori di sempre.

+0

In realtà il suo NRVO. –

0

Si noti che gli operatori sovraccarichi dovrebbero avere semantica intuitiva. Definire un unario + significa "valore assoluto", come si fa nel codice di esempio fornito, è estremamente confuso per i client. Gli operatori sui tipi definiti dall'utente dovrebbero comportarsi come nei tipi predefiniti. Ad esempio, +(-5) restituisce -5, non +5. Così, l'implementazione di operator+ dovrebbe apparire così:

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

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

Se si desidera fornire una funzione di valore assoluto, poi farlo:

BigInt abs(BigInt x) 
{ 
    x.makePositive(); 
    return x; 
} 
Problemi correlati