2009-03-24 2 views
86

Eventuali duplicati:
When should I use the new keyword in C++?Quando utilizzare "nuovo" e quando non farlo, in C++?

Quando devo utilizzare l'operatore "nuova" in C++? Vengo dallo sfondo C#/Java e l'istanziazione degli oggetti mi confonde.

Se ho creato una semplice classe denominata "Punto", quando creo un punto dovrei:

Point p1 = Point(0,0); 

o

Point* p1 = new Point(0, 0); 

Qualcuno può chiarire per me quando utilizzare il nuovo operatore e quando no?

duplicati di:

When should I use the new keyword in C++?

correlati:

About constructors/destructors and new/delete operators in C++ for custom objects

Proper stack and heap usage in C++?

+0

duplicato - troppe volte per contare –

+0

come ha detto Neil, questo è stato chiesto innumerevoli volte. – Naveen

risposta

110

Si dovrebbe usare new quando desideri che un oggetto rimanga in esistenza fino a quando non lo hai delete. Se non si utilizza new, l'oggetto verrà distrutto quando esce dall'ambito. Alcuni esempi di questo sono:

void foo() 
{ 
    Point p = Point(0,0); 
} // p is now destroyed. 

for (...) 
{ 
    Point p = Point(0,0); 
} // p is destroyed after each loop 

Alcuni diranno che l'uso di new decide se l'oggetto è sul mucchio o lo stack, ma questo è vero solo di variabili dichiarate all'interno di funzioni.

Nell'esempio seguente, la posizione di "p" sarà dove viene assegnato l'oggetto contenente, Foo. Preferisco chiamare questa allocazione "sul posto".

class Foo 
{ 

    Point p; 
}; // p will be automatically destroyed when foo is. 

allocazione (e liberazione) oggetti con l'uso di new è molto più costoso che se sono allocati sul posto per cui il suo uso deve essere limitato a dove necessario.

Un secondo esempio di quando allocare tramite new è per gli array. Non è possibile * modificare la dimensione di un array sul posto o di uno stack in fase di esecuzione, in modo che, quando è necessario un array di dimensioni indeterminate, questo debba essere assegnato tramite nuovo.

E.g.

void foo(int size) 
{ 
    Point* pointArray = new Point[size]; 
    ... 
    delete [] pointArray; 
} 

(* nitpicking preventiva - sì, ci sono le estensioni che consentono allocazioni dello stack di dimensioni variabili).

+2

+1 Ricorda che è necessario eliminare manualmente il puntatore new.ed eliminare p1; –

+6

+1 bello. ricorda che il primo può essere scritto come Punto p (0, 0); pure. la sintassi = .. potrebbe fargli pensare che p sia in qualche modo un puntatore a cui è assegnato qualcosa. –

+0

@Andrew Grant Se devi usare di nuovo 'shared_ptr' o' unique_prt'. che sono stati introdotti in C++ 11 STL i puntatori condivisi faranno automaticamente la cancellazione del libro. nota per deleter array predefinito fornito da 'chiamate shared_ptr' cancellare, non eliminare [] quindi utilizzare le funzioni lambda ' std :: shared_ptr p (new int [10], [] (int * p) { delete [ ] p; }); ' o ' std :: shared_ptr p (new int [10], std :: default_delete ()); ' o utilizzando assistenza fornite da unique_ptr che chiama delete [ ] 'std :: unique_ptr p (nuovo int [10], [] (int * p) { elimina [] p; }); ' – katta

9

Dai uno sguardo a this question e this question per alcune buone risposte sull'istanza di oggetti C++.

Questa idea di base è che gli oggetti istanziati nell'heap (utilizzando nuovo) devono essere puliti manualmente, quelli istanziati nello stack (senza nuovo) vengono automaticamente ripuliti quando escono dall'ambito.

void SomeFunc() 
{ 
    Point p1 = Point(0,0); 
} // p1 is automatically freed 

void SomeFunc2() 
{ 
    Point *p1 = new Point(0,0); 
    delete p1; // p1 is leaked unless it gets deleted 
} 
1

Nuovo è sempre utilizzato per allocare la memoria dinamica, che deve quindi essere liberata.

Facendo la prima opzione, tale memoria verrà automaticamente liberata quando l'ambito viene perso.

Point p1 = Point(0,0); //This is if you want to be safe and don't want to keep the memory outside this function. 

Point* p2 = new Point(0, 0); //This must be freed manually. with... 
delete p2; 
4

È consigliabile utilizzare nuovo quando si desidera creare un oggetto nell'heap anziché nella pila. Ciò consente di accedere a un oggetto dall'esterno della funzione o della procedura corrente, tramite l'ausilio di puntatori.

Potrebbe essere utile consultare i puntatori e la gestione della memoria in C++ poiché sono cose che difficilmente si sono incontrate in altre lingue.

+0

Nuovo non garantisce l'allocazione dell'heap e semplicemente evitando il nuovo non garantisce l'allocazione dello stack. –