2012-01-08 14 views
6

Ora sto imparando i medici e ho qualche domanda. A queste linee:Creazione e costruttore di oggetti C++

Foo obj(args); 

Foo obj2; 
obj = Foo(args); 

Foo obj3 = Foo(args); 

Prima parte: solo 1 costruttore chiamato (Foo) e obj è inizializzato. Quindi, 1 creazione di oggetti.

Seconda parte: creazione dell'oggetto temporaneo obj2, chiamata ctor predefinito per esso. Le prossime linee creiamo un'altra copia di Foo e passiamo la sua copia in operator=(). È giusto? Quindi, 3 oggetti temporanei locali, 2 chiamate del costruttore.

terza parte: creare 1 oggetto Foo e passarlo di copia negli operator=(). Quindi, 2 oggetti temprorary e 1 ctor calling.

Ho capito bene? E se è vero, il compilatore (l'ultimo gcc, ad esempio) ottimizzerà questi casi comuni?

+0

'operator =()' di solito riceve il suo argomento per riferimento, quindi nessuna copia nel chiamarlo. – rodrigo

+0

obj3 viene effettivamente creato utilizzando il costruttore della copia non l'operatore di assegnazione. –

risposta

6

farò commentare la terza prima:

Foo obj3=Foo(args); 

Non usa operator= che si chiama copia-assegnazione. Invece invoca copy-constructor (teoricamente). Non c'è nessun incarico qui. Quindi, in teoria, c'è la creazione di due oggetti, uno è temporaneo e l'altro è obj3. Il compilatore potrebbe ottimizzare il codice, eliminando completamente la creazione di oggetti temporanei.

Ora, il secondo:

Foo obj2;   //one object creation 
obj = Foo(args); //a temporary object creation on the RHS 

Qui la prima riga crea un oggetto, chiamando il costruttore di default. Quindi chiama operator= passando l'oggetto temporaneo creato dall'espressione Foo(args). Quindi ci sono due oggetti solo il operator= prende l'argomento dal riferimento const (che è quello che dovrebbe fare).

E per quanto riguarda il primo, hai ragione.

+0

Ok, grazie. Ma comunque, nel primo caso viene creato solo 1 oggetto di tipo 'Foo', nel terzo uno: 2 oggetti? – Ockonal

+0

No, secondo le specifiche, la parte 1 e la parte 3 sono due modi per specificare la stessa cosa. Non c'è differenza nell'implementazione. –

+2

@MrLister: No. C'è una sottile differenza tra '1' e' 3'. Basta scrivere un codice di prova e rendere 'copy' il costruttore della copia. Il primo si compilerà, il terzo no! – Nawaz

3
  1. Sì, Foo obj(args) crea un oggetto Foo e chiama il ctor una volta.

  2. obj2 non è considerato un oggetto temporaneo. Ma proprio come 1 Foo obj2 crea un oggetto e chiama il Foo ctor. Supponendo che si intendesse obj2 = Foo(args) per la riga successiva, questa linea crea un oggetto Foo temporaneo e quindi chiama obj2.operator=(). Quindi per questo secondo esempio c'è solo un singolo oggetto temporaneo, un singolo non temporaneo, i foo ctors sono chiamati due volte (una volta per il non temporaneo, una volta per il temporaneo) e l'operatore =() viene chiamato una volta.

  3. No, questa linea non chiama operator=(). Quando si inizializza = con la sintassi =, è quasi come se si usassero invece le parentesi: Foo obj3(Foo(args)); Quindi questa linea crea un oggetto temporaneo, quindi chiama Foo copy ctor per inizializzare obj3 usando quell'oggetto temporaneo.

1

La terminologia è un po 'confusa.

Gli oggetti obj, obj2obj3 non sono denominati "oggetti temporanei". Solo l'istanza creata nella riga 3 prima di essere assegnata a obj è un oggetto temporaneo.

Inoltre, non si crea "una copia di Foo", si crea "un'istanza di Foo" o "un oggetto di tipo Foo".

Problemi correlati