C ++ costruttore di copia, provvisori e copia semantica
Domanda
Per questo programma
#include <iostream>
using std::cout;
struct C
{
C() { cout << "Default C called!\n"; }
C(const C &rhs) { cout << "CC called!\n"; }
};
const C f()
{
cout << "Entered f()!\n";
return C();
}
int main()
{
C a = f();
C b = a;
return 0;
}
l'output che ottengo è:
Entered f()!
Default C called!
CC called!
Dal f()
sta tornando per valore, deve restituire una temporanea. Come T a = x;
è T a(x);
, non sarebbe chiamare il costruttore di copia per la costruzione di a
, con la temporanea passato-in come argomento?
Soluzione
Dal
f()
sta tornando per valore, deve restituire una temporanea. ComeT a = x;
èT a(x);
, non sarebbe chiamare il costruttore di copia per la costruzione dia
, con la temporanea passato-in come argomento?
Look up Return Value Optimization. Questo è attivata per impostazione predefinita. Se siete su Windows utilizzando MSVC 2005+ è possibile utilizzare /Od
per disattivarlo e ottenere il risultato desiderato (o -fno-elide-constructors
su GCC). Inoltre, per MSVC vedi questo articolo .
12.8 oggetti di classe Copia
15 Quando vengono soddisfatti determinati criteri, un attuazione è consentito omettere il copia costruzione di un oggetto classe, anche se il costruttore di copia e / o distruttore per l'oggetto avere lato effetti. In questi casi, il attuazione considera la sorgente e destinazione dell'operazione di copia omessa come semplicemente due modi diversi di riferimento allo stesso oggetto, e distruzione di tale oggetto avviene a la successiva dei tempi in cui i due oggetti avrebbero state distrutte senza optimization.115 Questa elisione copia le operazioni sono permesse con la segue circostanze (che può essere combinati per eliminare multiplo copie):
- in una dichiarazione di ritorno in funzione con un tipo di classe di ritorno, quando l'espressione è il nome di un non volatile oggetto automatica con il stesso cv-qualificato tipo della funzione tipo di ritorno, la copia operazione può essere omesso da costruire l'oggetto automatica direttamente nel ritorno della funzione valore - in una rimessa espressione, quando l'operando è il nome di un non volatile oggetto automatico, la operazione di copia dal operando al oggetto eccezione (15.1) può essere omessa costruendo l'oggetto automatica direttamente nell'oggetto eccezione
- quando un oggetto di classe temporaneo che ha non è stato associato a un riferimento (12.2) sarebbe stato copiato su un oggetto di classe con lo stesso tipo di cv-qualificato, la copia operazione può essere omesso da costruire l'oggetto temporaneo direttamente nella destinazione della copia omesso
- quando il eccezione Dichiarazione di un'eccezione handler (clausola 15) dichiara un oggetto dello stesso tipo (ad eccezione cv-qualificazione) come l'eccezione oggetto (15.1), l'operazione di copia può essere omessa trattando la eccezioni dichiarazione come alias di l'oggetto eccezione se il significato di il programma sarà invariato, tranne per l'esecuzione di costruttori e distruttori per l'oggetto dichiarato dal l'eccezione-dichiarazione.
Nota: l'enfasi è mia
Altri suggerimenti
Questo è un esempio di Return Value Optimization (RVO) caratteristiche che il vostro compilatore supporta.
Un costruttore di copia potrebbe non essere chiamata quando si torna al valore.
opzione Usa -fno-elide-constructors
su GCC per attivare quella funzione.
Credo si chiami valore di ottimizzazione di ritorno .
Presumo quando ritorna f()
C
oggetto l'oggetto viene allocato nello spazio dello stack del metodo chiamante quindi nessuna copia è necessaria per inizializzare C a
. Questo è il vostro default C called
.
C b = a
Questo fa sì che un costruttore di copia, quindi, il vostro CC called
.
A proposito, l'esempio a wiki sembra abbastanza simile simile al codice.