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?

È stato utile?

Soluzione

  

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?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top