Differenza tra "nuovo operatore" e "operatore nuovo"?


126

Qual è la differenza tra "new operator" e "operator new"?


3
Ciao, puoi chiarire la domanda? Sembra che ci sia un errore di battitura da qualche parte.
Dima Malenko,

17
La domanda è formulata correttamente, vedere le risposte di seguito. Il metodo per allocare dinamicamente la memoria consiste nell'utilizzare l' newoperatore. Questo operatore può essere sovraccaricato. Per distinguere tra l'operatore predefinito e una versione sovraccarica, il valore predefinito è chiamato "nuovo operatore" e la versione sovraccarica è chiamato "operatore nuovo".
Thomas Matthews,

2
Come farlo. Sono nuovo e ignaro.
Sandeep

Risposte:


127

Di solito provo a formulare le cose in modo diverso per differenziarle un po 'meglio, ma in ogni caso è una buona domanda.

L'operatore new è una funzione che alloca memoria non elaborata, almeno concettualmente, non è molto diverso da malloc(). Sebbene sia abbastanza insolito a meno che tu non stia scrivendo qualcosa come il tuo contenitore, puoi chiamare l'operatore new direttamente, come:

char *x = static_cast<char *>(operator new(100));

È anche possibile sovraccaricare l'operatore new globalmente o per una classe specifica. IIRC, la firma è:

void *operator new(size_t);

Ovviamente, se sovraccarichi un operatore new (globale o per una classe), vorrai / dovrai anche sovraccaricare anche l'operatore corrispondente delete. Per quel che vale, c'è anche un operatore separato new [] che viene utilizzato per allocare la memoria per gli array, ma quasi certamente faresti meglio a ignorare completamente tutto quel casino.

Il nuovo operatore è quello che usi normalmente per creare un oggetto dal negozio gratuito:

my_class *x = new my_class(0);

La differenza tra i due è che l'operatore new alloca solo la memoria non elaborata, nient'altro. Il nuovo operatore inizia usando l'operatore new per allocare la memoria, ma poi richiama il costruttore per il giusto tipo di oggetto, quindi il risultato è un vero oggetto live creato in quella memoria. Se quell'oggetto contiene altri oggetti (incorporati o come classi base) anche quei costruttori vengono richiamati.


18
+1, per quanto riguarda un diverso fraseggio, lo standard utilizza una nuova espressione tutt'intorno e solo una volta utilizza l' operatore nuovo per riferirsi al luogo della chiamata. Tendo a fare lo stesso: operatore nuovo per l' allocatore e nuova espressione per l'uso.
David Rodríguez - dribeas

3
Una nuova espressione è l'intera frase che inizia con nuovo. Allora come si chiama solo la parte "nuova"? Se è sbagliato chiamarlo operatore new, non dovremmo chiamare "sizeof" l'operatore sizeof, o & l'operatore address-of (quando si comporta come tale).
Kaz

1
Facendo seguito all'osservazione di Kaz, forse la domanda dovrebbe essere riformulata come, qual è la differenza tra il nuovo operatore e l'operatore nuovo operatore? :)
CS


2
@antred: lo rilasceresti con qualcosa di simile operator delete(x);.
Jerry Coffin

35

"operatore nuovo"

class Foo
{
public:
        void* operator new( size_t );
}

"nuovo operatore":

Foo* foo = new Foo();

In questo esempio, new Foo()callsFoo::operator new()

In altre parole, "nuovo operatore" chiama " operator new()" proprio come l'operatore + chiamaoperator +()


13
newnon è un operatore in C ++. sizeof, ad esempio, è un operatore, ma newe deletenon lo sono. newe deletesono parole chiave e i costrutti sintattici che queste parole chiave formano sono chiamati nuova espressione e cancellazione-espressione .
AnT

2
Uh, semmai, sizeofè il costrutto sintattico e newe deletesono entrambi operatori validi, legali e sovraccaricabili. Da tutto quello che ho mai visto, newe deletesono entrambi operatori. Vedi [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Austin Hyde

7
Non corretto. La terminologia ufficiale C ++ è la terminologia definita dalla specifica del linguaggio, non da qualche sito web. Nella specifica del linguaggio non esiste un termine come "nuovo operatore", ma esiste un termine come " operator newfunzione". Anche in questo caso, sizeofviene esplicitamente denominato "operatore", mentre newe nondelete vengono mai indicati come operatori.
AnT

6
AndreyT: Sbagliato. Lo standard C ++ chiama "nuovo" un operatore, vedere 13.5 / 1.

3
@AndreyT: Ho pensato, come fai tu, che l' operatore nuovo fosse l' allocatore e la nuova espressione gli usi. Ho esaminato e verificato che nel §5.3.4 / 3 lo standard corrente utilizzi il termine nuovo operatore . Più avanti nel §5.3.4 / 8 nomina le funzioni dell'allocatore come operatore nuovo e operatore nuovo []
David Rodríguez - dribeas

22

Di seguito è riportata la citazione dal libro C ++ più efficace di Scott Meyers:

Il nuovo operatore chiama una funzione per eseguire l'allocazione di memoria richiesta ed è possibile riscrivere o sovraccaricare quella funzione per modificarne il comportamento. Il nome della funzione che il nuovo operatore chiama per allocare la memoria è operatore nuovo.


7
Il termine è ovviamente inventato dall'autore del libro (o, forse, preso in prestito da qualche fonte obsoleta). Nella nomenclatura formale C ++ non esiste un termine come "nuovo operatore".
AnT

2
@AndreyT: ho cercato "new operator" in C ++ 11 e l'ho trovato referenziato in quattro punti. Nello specifico, due riferimenti al "posizionamento nuovo operatore"
Mooing Duck

11

Non c'è differenza tra "nuovo operatore" e "nuovo operatore". Entrambi si riferiscono alla stessa cosa: la funzione sovraccaricabile / sostituibile operator newche in genere esegue l'allocazione di memoria non elaborata per oggetti creati da nuove espressioni .

Si noti inoltre che nessuno dei due termini è presente nella specifica della lingua (che è la fonte che definisce la terminologia ufficiale).

Quando si utilizza newnel programma per creare un oggetto, si parla di nuova espressione . La nuova espressione consiste in parole chiave newe parti sintattiche aggiuntive definite dalla grammatica. Nessuna parte della sintassi di questa espressione viene mai chiamata "operatore".

La funzione di allocazione della memoria non elaborata operator newviene ufficialmente definita solo " operator newfunzione". Nota che le parole operatore newin questa sequenza sono solo due parole chiave del linguaggio C ++ separate. Non formano un termine inglese "operatore nuovo". Da nessuna parte nella specifica della lingua troverai riferimenti a "operatore nuovo" come termine inglese. Ogni volta questa è solo una combinazione di due parole chiave indipendenti che producono la sintassi di dichiarazione per una funzione di allocazione della memoria.

Di nuovo, nel curriculum: formalmente in C ++ non ci sono termini in lingua inglese come "operator new" o "new operator". La prima sequenza è presente nella specifica della lingua come una semplice combinazione di parole chiave, non come un termine inglese. Quest'ultimo non è affatto presente.


14
Sembri perso in qualche pedante masturbazione mentale. Lo standard è vago in alcuni punti, e questo è uno di questi. Ha senso tanto "discutere il nuovo operatore" quanto "discutere l'operatore più" o "discutere l'operatore +".

7

Quando si crea un nuovo oggetto, la memoria viene allocata utilizzando l' operatore new, quindi viene richiamato il costruttore per inizializzare la memoria. Il nuovo operatore fa sia l'allocazione che l'inizializzazione, mentre l'operatore nuovo fa solo l'allocazione.


6

La domanda dell'OP non è formulata correttamente. È meglio impostare la fase come "Differenza tra" operatore nuovo "e" nuova espressione "?" Nota "nuovo operatore" spesso si riferisce anche a "nuova funzione operatore".

E ci sono molte risposte corrette in giro, di seguito è la mia:

1> "nuova espressione" chiama "operatore nuovo" per allocare memoria non elaborata, quindi chiama il costruttore

apple * p = new apple(); //new expression

2> 'operator new' alloca solo memoria grezza, non molta differenza rispetto a malloc

void* mem = operator new(sizeof(apple)); //just like calling malloc()
apple* p2 = new(mem) apple(1); //call construct here using placement new.

2

Il nuovo operatore : C ++ supporta l'allocazione dinamica di oggetti utilizzando l'operatore nuovo. Il nuovo operatore alloca memoria per gli oggetti da un pool denominato archivio gratuito. Il nuovo operatore chiama la funzione speciale operatore nuovo.

operator new : se la richiesta è per zero byte di memoria, l'operatore new restituisce un puntatore a un oggetto distinto (ovvero, chiamate ripetute a operator new restituiscono puntatori diversi). Se la memoria è insufficiente per la richiesta di allocazione, l'operatore new restituisce NULL o genera un'eccezione. Il primo argomento dell'operatore new deve essere di tipo size_t (un tipo definito in STDDEF.H) e il tipo restituito è sempre void *.

Ecco i collegamenti MSDN per maggiori dettagli:

La nuova funzione operatore

Il nuovo operatore


1
Leggera precisazione: il nuovo operatore di mancato piazzamento deve sempre lanciare in caso di mancata allocazione (secondo lo standard); e le forme di posizionamento, come ::new(std::nothrow), possono fare entrambe le cose (l'esempio specifico restituisce un puntatore nullo).

1
  1. new è un operatore oltre che una parola chiave.

    vedere [1] In 2.13 && In 2.12.

  2. new fa due cose: T * t = new T (arg);

    1) alloca memoria per l'oggetto: void * ptr = operator new (sizeof (T));

    // l' operatore new è una funzione (proprio come malloc in c), non un operatore (vedere [1] in 3.7.4). Ma l'articolo 7 [2] dice che è anche un operatore. Secondo me, la differenza tra operatore e funzione è piccola e puoi vederla quando ricordi che l'operatore di sovraccarico è implementato dalle funzioni.

    // possiamo sovraccaricare questo operatore / funzione (operatore nuovo) facendo ciò che vogliamo proprio qui.

    2) inizializza l'oggetto nella memoria allocata: chiama T :: T (arg) su ptr

    // solo il compilatore può farlo. Né io né tu possiamo.

    // anche il compilatore richiamerà i costruttori degli oggetti membri e il costruttore della classe base se T li ha. E questa invocazione è ricorsiva. Solo il compilatore può farlo.

  3. Quindi, operatore nuovo fa parte delle missioni di nuovo, e solo in questa parte possiamo fare qualcosa.

    [1]: ISO / IEC, N3690. http://ww.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

    [2]: Meyers, Scott. Efficace C ++, 3 °.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.