2010-05-12 26 views
15

È valido memorizzare il valore restituito di un oggetto in un riferimento?Memorizza valore di ritorno della funzione in riferimento C++

class A { ... }; 
A myFunction() 
{ 
    A myObject; 
    return myObject; 
} //myObject goes out of scope here 

void mySecondFunction() 
{ 
    A& mySecondObject = myFunction(); 
} 

E 'possibile fare questo al fine di evitare di copiare myObject a mySecondObject? myObject non è più necessario e dovrebbe essere esattamente lo stesso di mySecondObject, quindi in teoria sarebbe più veloce solo per passare la proprietà dell'oggetto da un oggetto a un altro. (Questo è possibile anche utilizzando il puntatore condiviso di boost ma che ha il sovraccarico del puntatore condiviso.)

Grazie in anticipo.

risposta

19

Non è consentito associare il riferimento temporaneo a un riferimento non const, ma se si crea il riferimento const si estende la durata del riferimento temporaneo al riferimento, vedere this Danny Kalev post about it.

In breve:

const A& mySecondObject = myFunction(); 
+1

Ti capita di sapere perché questo non è permesso? – Mehrdad

+0

Non sono sicuro, ma suppongo che il motivo sia che consentire un riferimento non const significherebbe che al compilatore sarebbe richiesto di determinare quando il riferimento viene nuovamente assegnato. Ritengo che questo sia normalmente considerato parte dell'analisi dell'ambito dinamico e non utilizzato nello standard C++. Nel caso const, invece, è necessario determinare solo la durata statica del riferimento. Questa analisi è probabilmente già richiesta in altri casi ed è stata quindi ritenuta accettabile. –

+0

Si può anche notare che questa è una caratteristica di tracciamento puntatore piuttosto semplicistica, e che si potrebbe immaginare un sistema più avanzato. Ma in generale credo che il C++ voglia evitare questo problema e delegarlo invece al programmatore. Ecco a cosa servono gli indicatori intelligenti. –

3

È possibile con un riferimento const.

myFunction restituisce per valore, in modo che il valore di ritorno sia un oggetto temporaneo. È possibile associare un riferimento temporaneo a un riferimento const e la durata del temporaneo viene estesa alla durata del riferimento. Non è possibile associare un riferimento temporaneo a un riferimento non const (sfortunatamente).

Il valore restituito di myFunction potrebbe essere un copia di myObject. Sul lato positivo, copia costruttore elision (noto anche come "ottimizzazione del valore di ritorno con nome" in questo caso) consente al compilatore di costruire myObject direttamente nel temporaneo che è il valore di ritorno di myFunction, presumibilmente situato da qualche parte nella pila del codice chiamante. In tal caso, quando myObject esce dall'ambito, l'oggetto non viene effettivamente distrutto. L'ottimizzazione è comunemente implementata - ad esempio GCC (di solito?) Lo fa anche senza i flag di ottimizzazione.

copia ctor elisione permette anche il compilatore per evitare la riproduzione se avete fatto:

A mySecondObject = myFunction(); 

Ciò richiede l'applicazione di entrambe le forme giuridiche di copia ctor elisione: (1) la restituzione di un valore denominato da una funzione, e (2) inizializzare un oggetto da un temporaneo.

5

Potresti essere interessato allo return-by-value optimization che molti compilatori fanno per evitare di chiamare il costruttore di copie.

+0

Questa è una di quelle idee che sto cercando. Non posso visitare la pagina ma credo che https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization sarebbe simile. – konsolebox

Problemi correlati