26

Stavo guardando la firma del nuovo operatore. Quale è:nuovo operatore per allocazione memoria su heap

void* operator new (std::size_t size) throw (std::bad_alloc); 

Ma quando usiamo questo operatore, non usiamo mai un cast. cioè

int *arr = new int; 

Quindi, come si fa a C++ converte un puntatore di tipo void* a int* in questo caso. Perché, anche restituisce un void* e dobbiamo utilizzare esplicitamente un cast.

risposta

39

C'è una differenza molto sottile in C++ tra operator new e l'operatore new. (Leggi di nuovo ... l'ordine è importante!)

La funzione operator new è l'analogo C++ della funzione malloc di C. È un allocatore di memoria non elaborato la cui responsabilità è esclusivamente quella di produrre un blocco di memoria su cui costruire oggetti. Non invoca costruttori, perché non è questo il suo lavoro. Solitamente, non vedrai operator new usato direttamente nel codice C++; sembra un po 'strano Ad esempio:

void* memory = operator new(137); // Allocate at least 137 bytes 

L'operatore new è una parola chiave che è responsabile per l'allocazione di memoria per un oggetto e richiamando suo costruttore. Questo è ciò che si incontra più comunemente nel codice C++. Quando si scrive

int* myInt = new int; 

Si sta utilizzando il nuovo operatore per assegnare un nuovo numero intero. Internamente, l'operatore new funziona grosso modo così:

  1. allocare memoria per contenere l'oggetto richiesto utilizzando operator new.
  2. Richiamare il costruttore oggetto, se presente. Se ciò genera un'eccezione, liberare la memoria precedente con operator delete, quindi propagare l'eccezione.
  3. Restituisce un puntatore all'oggetto di nuova costruzione.

Poiché l'operatore new e operator new sono separati, è possibile utilizzare la parola chiave new per costruire oggetti senza effettivamente allocare alcuna memoria. Ad esempio, il famoso posizionamento nuovo consente di creare un oggetto con un indirizzo di memoria arbitrario nella memoria fornita dall'utente. Per esempio:

T* memory = (T*) malloc(sizeof(T)); // Allocate a raw buffer 
new (memory) T(); // Construct a new T in the buffer pointed at by 'memory.' 

sovraccarico l'operatore new definendo una consuetudine operator new funzione consente di utilizzare new in questo modo; si specifica come avviene l'allocazione e il compilatore C++ lo collegherà all'operatore new.

Nel caso in cui sei curioso, la parola chiave delete funziona allo stesso modo.C'è una funzione di deallocazione chiamata operator delete responsabile per lo smaltimento della memoria, e anche un operatore delete responsabile per invocare distruttori di oggetti e liberare memoria. Tuttavia, operator new e operator delete possono essere utilizzati al di fuori di questi contesti al posto di C malloc e free, ad esempio.

+0

Il secondo passo dovrebbe essere "Richiama il costruttore oggetto, se presente. Se questo genera * qualsiasi eccezione *, libera la memoria sopra e propagare l'eccezione." – GManNickG

+0

@ GMan- Grazie per averlo scoperto! Colpa mia. Lo aggiusterò. – templatetypedef

+0

Davvero un'ottima spiegazione. Molte grazie !!! –

4

Si confonde l'espressione new con la funzione operator new(). Quando il primo è compilato, il compilatore, tra le altre cose, genera una chiamata alla funzione operator new() e passa la dimensione sufficiente a contenere il tipo menzionato nell'espressione new e quindi viene restituito un puntatore di quel tipo.

+0

A chi ha downvoted: cosa c'è di sbagliato in questa risposta? Sembra perfettamente corretto. – templatetypedef