2012-01-22 8 views
8

In C++ non è consentito assegnare un puntatore void * a nessun puntatore integrale senza un cast esplicito. Ciò richiede l'uso di un static_cast.Perché il nuovo operatore può tornare * vuoto a ogni tipo di puntatore?

Ma che cosa è questo:

int* iptr = new int; 

So che il nuovo operatore è definito come segue:

void* operator new(size_t); 

Come si fa a C++ gestire questa situazione? So che questa è una domanda di base, ma importante. So anche che il codice di basso livello deve utilizzare void. Ma come può questo incarico essere legale? iptr è un puntatore a un int e new restituisce un puntatore a void, che dovrebbe attivare un messaggio del tipo "errore: conversione non valida da 'void *' a 'int *' [-fpermissive]".

+5

Leggere questo: http://stackoverflow.com/questions/2697892/what-is-return-type-of-new-in-c; operatore nuove e nuove espressioni non sono la stessa cosa. – Mat

+1

Inoltre, questo: http://stackoverflow.com/questions/2941888/how-operator-new-calls-the-constructor-of-class - Credo che entrambi rispondano alla tua domanda. – Mat

+0

Inoltre: grazie a te Mat! – Peter

risposta

19

Hai confuso l'operatore nuovo e l'operatore nuovo. Nessun problema, lo fanno tutti. Sono quasi la stessa cosa, tranne che sono diversi.

La funzione void* operator new(size_t) acquisisce un blocco di memoria grezza e non tipizzata da qualsiasi albero su cui cresce e lo restituisce al programma.

void* raw_memory = ::operator new(42); 

È una funzione ordinaria con un nome un po 'strano.

L'operatore nuovo non è una funzione e non una chiamata di funzione. È un costrutto linguistico separato. Prende la memoria grezza (normalmente, restituita dalla funzione void* operator new(size_t)) e la trasforma in un oggetto chiamando un costruttore. Quindi restituisce un puntatore correttamente digitato sull'oggetto appena creato.

Fish* f = new Fish; 

UPDATE Naturalmente, c'è anche la eliminare operatore (l'opposto dell'operatore nuovo) e la funzione void operator delete(void*) (l'opposto della funzione void* operator new(size_t)).

ci sono anche la nuova [] operatore , il delete [] operatore, la funzione void* operator new[](size_t), e la funzione void operator delete[](void*); si occupano di matrici di oggetti (rispetto ai singoli oggetti).

Esistono anche moduli di "inserimento nuovo" che non chiamano nessuna delle funzioni operator new per la memoria nuova, ma richiedono invece un puntatore esplicito alla memoria non elaborata. Non hanno corrispondenti moduli di "cancellazione" integrati. Puoi tirare il tuo se sei così propenso, ma mi rifiuto di parlare di tutto ciò pur essendo sobrio.

+1

+1 per "Sono quasi la stessa cosa, tranne che sono diversi." –

+0

Usi 'delete' su entrambi? –

+0

@Seth: No, 'delete void_ptr;' è un comportamento non definito.Dovresti usare ':: operator delete (void_ptr_from_operator_new);' – Xeo

Problemi correlati