2009-11-19 13 views
50

questa è una domanda molto semplice ma non ho fatto C++ correttamente per anni e quindi sono un po 'sconcertato da questo. Inoltre, non è la cosa più semplice (almeno per me) per cercare su internet, non per provare.C++ Object senza nuovo

Perché non utilizza la parola chiave new e come funziona?

Fondamentalmente, cosa sta succedendo qui?

CPlayer newPlayer = CPlayer(position, attacker); 

risposta

42

Questa espressione:

CPlayer(position, attacker) 

crea un oggetto temporaneo di tipo CPlayer utilizzando il costruttore sopra, quindi:

CPlayer newPlayer =...; 

Il citato oggetto temporaneo viene copiato utilizzando il costruttore copia newPlayer . Un modo migliore è quello di scrivere la seguente evitare provvisori:

CPlayer newPlayer(position, attacker); 
+0

Brillante, grazie. –

+5

In realtà il compilatore probabilmente lo ottimizzerà. In tal caso, il costruttore della copia non verrà richiamato. http://stackoverflow.com/questions/1758142/why-copy-constructor-is-not-called-in-this-case – BostonLogan

+4

Un'assegnazione in una dichiarazione non è meno efficiente dell'uso della sintassi del costruttore. Se fossero state dichiarazioni separate, l'osservazione sui temporari sarebbe corretta. L'essenza è che questo dichiara un CPlayer (tipicamente sullo stack) piuttosto che allocare lo spazio per esso dal negozio gratuito (heap). –

31

Quanto sopra costruisce un oggetto CPlayer in pila, quindi non ha bisogno new. È necessario utilizzare solo new se si sta tentando di allocare un oggetto CPlayer nell'heap. Se si utilizza l'allocazione heap, il codice sarebbe simile a questa:

CPlayer *newPlayer = new CPlayer(position, attacker); 

Si noti che in questo caso stiamo usando un puntatore ad un oggetto CPlayer che dovrà essere ripulito da una chiamata corrispondente a delete . Un oggetto allocato nello stack verrà distrutto automaticamente quando esce dallo scope.

In realtà sarebbe stato più facile e più ovvia di scrivere:

CPlayer newPlayer(position, attacker); 

Un sacco di compilatori ottimizzeranno la versione che avete inviato a quanto sopra in ogni caso ed è più chiaro da leggere.

+0

Non penso che sia corretto: "Un oggetto allocato sull'heap verrà distrutto automaticamente quando uscirà dall'ambito." – Valentin

+0

Hai ragione, volevo scrivere "stack", non "heap". Grazie per averlo indicato. –

+0

D'accordo su questo. Dovremmo mantenere il codice C++ nello stesso stile del codice C. Quindi 'CPlayer newPlayer (position, attacker);' è migliore di 'CPlayer newPlayer = CPlayer (posizione, attacker);' se vuoi creare una variabile stack. – tonga

4

newPlayer non si alloca dinamicamente variabile ma un auto, variabile pila-allocato:

CPlayer* newPlayer = new CPlayer(pos, attacker); 

è diverso da

CPlayer newPlayer = CPlayer(pos, attacker); 

newPlayer è allocato sulla pila tramite il CPlayer normale (posizione, attaccante invocazione del costruttore, anche se un po 'prolisso del solito

CPlayer newPlayer(pos, attacker); 

E 'fondamentalmente lo stesso che dire:

int i = int(3); 
+2

Attenzione qui. È una "inizializzazione della copia". Non è * un incarico. – sellibitze

+0

Sono corretto, non è un compito; anche il costruttore di copie non è coinvolto. Modifica la risposta di conseguenza. – digitalarbeiter

+2

Certo, il copy ctor è (almeno logicamente) coinvolto. Noterai che se rendi il tuo copy ctor privato. Quindi, questa inizializzazione della copia non funzionerà più. Lo standard C++ richiede un copyctor accessibile anche quando il compilatore è in grado di ottimizzare la copia. – sellibitze

8
CPlayer newPlayer = CPlayer(position, attacker); 

Questa linea crea un nuovo oggetto locale di tipo CPlayer. Nonostante il suo aspetto simile a una funzione, questo chiama semplicemente il costruttore di CPlayer. Non sono coinvolti temporaries o copying. L'oggetto denominato newPlayer vive finché l'ambito è incluso. Non si utilizza la parola chiave new perché C++ non è Java.

CPlayer* newPlayer = new CPlayer(position, attacker); 

Questa linea costruisce un oggetto CPlayer sul mucchio e definisce un puntatore chiamato newPlayer per indicare a esso. L'oggetto vive fino a quando qualcuno non lo ha delete.

+2

"Non ci sono temporanee o copie coinvolte" - Questo non è esattamente vero. Non esiste una tale garanzia. Ma ogni compilatore decente dovrebbe escludere la copia. – sellibitze