Posizionare un oggetto in una variabile perché ti è stato "detto che dovremmo evitare il più temporaneo possibile" è come usare variabili statiche perché ti è stato detto che i singleton sono cattivi - non stai davvero evitando il problema, solo il codice odore che viene fornito con la forma più comune del problema.
Come dice nvoigt, se vuoi evitare del tutto questo problema, devi cambiare il metodo in qualcosa che non crea oggetti. Tuttavia, potrebbe non essere possibile (forse non è possibile modificare il codice sorgente dell'oggetto?) O ragionevole (forse la classe ha altri metodi, e non si vuole rovinare la progettazione) per farlo. In tal caso, credo che il primo approccio (oggetto temporaneo senza nome) sia migliore.
La principale differenza tra i due approcci è quando verrà chiamato il distruttore dell'oggetto temporaneo. Se si tratta di un oggetto temporaneo con nome, verrà chiamato alla fine dell'ambito. Se si tratta di un oggetto temporaneo senza nome, verrà chiamato dopo la chiamata a get_content()
, quando l'oggetto non è più necessario.
Ho giocato un po 'con objdump
e ho scoperto che se metti solo queste due (o una) riga in una funzione, l'unica differenza tra i due è che nella versione senza nome l'oggetto viene distrutto prima il risultato di get_content
viene spostato a content
mentre nella versione con nome succede dopo.
Tuttavia, quando ho aggiunto un'istruzione per stampare content
dopo quelle righe, le cose diventano un po 'più complicate. La versione nominata ha prodotto il codice per chiamare il distruttore due volte - una volta alla fine della funzione, e una volta in un punto successivo che non viene mai eseguito ! O, dovrei dire, non viene mai eseguito nel flusso regolare della funzione .
Non ho familiarità con il modo in cui C ++ funziona in assembly-wise, ma presumo che questo abbia a che fare con la gestione delle eccezioni - quando il metodo di stampa (beh, operatore ...) lancia un'eccezione, il meccanismo di srotolamento dello stack ha bisogno essere in grado di chiamare i distruttori, quindi usa quel codice.
Per verificare questa ipotesi, ho aggiunto un'istruzione throw
a get_content
, e come mi aspettavo ora anche la versione senza nome ha ottenuto quel segmento di codice, poiché ora può anche ottenere un'eccezione prima che avvenga la normale distruzione . Ma ancora - gcc
è riuscito a ottimizzarlo quando non era necessario!
Quindi, in conclusione, scegli la versione senza nome! I compilatori moderni sono molto intelligenti ma non riescono a leggerti nella mente, quindi i suggerimenti che fornisci loro sulle tue intenzioni sono il lavoro migliore che possono fare. L'uso della versione senza nome induce all'ottimizzatore che è necessario solo l'oggetto per get_content
ed è libero di eliminarlo successivamente e ottimizzare le cose in questo modo. Più cose accadono tra la creazione di un oggetto e la sua distruzione, più è difficile per l'ottimizzatore ragionare sul suo ruolo.