2010-11-10 1 views
15

ho visto il codice come questo:perché operatore di call nuova esplicitamente

void *NewElts = operator new(NewCapacityInBytes); 

E chiamata corrispondente conseguente esplicitamente operator delete viene utilizzato in seguito.

Perché fare questo, invece di:

void *NewElts = new char[NewCapacityInBytes]; 

Perché chiamata esplicita a operator new e operator delete ??

+1

Hai messo le parentesi quadre sul secondo esempio di proposito? –

+0

Probabilmente inteso: 'new char [NewCapacityInBytes]' – MSalters

+0

@MSalters: hai ragione, corretto – zaharpopov

risposta

24

Chiamare esplicitamente operator new come quello chiama l'operatore globale "raw" nuovo. Global operator new restituisce un blocco di memoria non elaborato senza chiamare il costruttore dell'oggetto o eventuali sovraccarichi definiti dall'utente di new. Quindi, fondamentalmente, globale operator new è simile a malloc da C.

Quindi:

// Allocates space for a T, and calls T's constructor, 
// or calls a user-defined overload of new. 
// 
T* v = new T; 

// Allocates space for N instances of T, and calls T's 
// constructor on each, or calls a user-defined overload 
// of new[] 
// 
T* v = new T[N]; 

// Simply returns a raw byte array of `sizeof(T)` bytes. 
// No constructor is invoked. 
// 
void* v = ::operator new(sizeof(T)); 
+2

quando è utile? – zaharpopov

+6

@zaharpopov: un esempio potrebbe essere implementare un pool di memoria in cui allocare una grande porzione una volta e gli utenti del pool chiamerebbero funzioni che creano oggetti all'interno del blocco, invece di usare 'new'. A seconda del modello di allocazione, questo può fornire prestazioni migliori di 'new' e' delete'. –

+0

Ooo. Interessante. Non conoscevo * questo * angolo di C++. –

2

Se si chiama operatore new (bytesize), allora è possibile eliminarlo usando delete, mentre se si alloca tramite new char [ bytesize], quindi devi abbinarlo usando delete [], che è un abominio da evitare ove possibile. Questo è probabilmente il motivo principale per usarlo.

+1

Com'è un abominio? –

+3

Se si assegna tramite 'operatore new new 'globale, è possibile deallocarlo utilizzando' operator delete 'globale. Ma l'operatore globale delete non chiamerà il distruttore. Quindi, se effettivamente costruisci un oggetto usando il posizionamento new dopo aver chiamato global 'operator new', allora globale' operator delete' da solo non è sufficiente per distruggere l'oggetto. È necessario anche richiamare esplicitamente il distruttore prima di deallocare la memoria. In sostanza, sia 'operatore new' che' operator delete' consentono di disaccoppiare allocazione/deallocazione e inizializzazione/distruzione dell'oggetto. –

+0

@Charles: non ha posizionato nulla di nuovo, e quella memoria non ha bisogno di essere distrutta. Come una forma di allocazione della memoria puramente, quindi operatore new() è la scommessa più sicura perché non ha bisogno di eliminare irritante [] o inusuale() per deallocare. @Steve: delete [] è un abominio perché non è necessario. Non è come quando si usa l'operatore new e non new [], che l'heap magicamente non ha bisogno di memorizzare la dimensione del blocco o qualcosa del genere. – Puppy

6

se si scrive:

T *p = new T; 

che alloca memoria sufficiente per contenere un T, poi costruisce il T in esso. Se si scrive:

T *p = ::operator new(sizeof(T)); 

che alloca memoria sufficiente per contenere un T, ma non costruisce la T. Uno dei momenti si potrebbe vedere questo è quando le persone sono anche utilizzando nuova collocazione:

T *p = ::operator new(sizeof(T)); // allocate memory for a T 
new (p) T; // construct a T into the allocated memory 
p->~T(); // destroy the T again 
::operator delete(p); // deallocate the memory 
1

Utilizzarlo quando si desidera allocare un blocco di memoria "raw" e non si desidera creare nulla in tale memoria.

C'è poca differenza pratica tra l'allocazione di un blocco di memoria non elaborata e la "costruzione" di un array di caratteri, ma l'operatore new indica chiaramente l'intenzione a chiunque legga il codice che è importante.