Unterschied zwischen 'neuer Operator' und 'neuer Operator'?

126

Was ist der Unterschied zwischen "neuer Operator" und "neuer Operator"?

Sandeep
quelle
3
Hallo, können Sie bitte die Frage klären? Sieht so aus, als gäbe es irgendwo Tippfehler.
Dima Malenko
17
Die Frage ist richtig formuliert, siehe Antworten unten. Die Methode zum dynamischen Zuweisen von Speicher besteht in der Verwendung des newOperators. Dieser Operator kann überlastet werden. Um zwischen dem Standardoperator und einer überladenen Version zu unterscheiden, wird der Standardoperator "neuer Operator" und die überladene Version "Operator neu" genannt.
Thomas Matthews
2
Wie geht das. Ich bin neu und ahnungslos.
Sandeep

Antworten:

127

Normalerweise versuche ich, die Dinge anders zu formulieren, um die beiden etwas besser zu unterscheiden, aber das ist auf jeden Fall eine gute Frage.

Operator new ist eine Funktion, die Rohspeicher zuweist - zumindest konzeptionell unterscheidet sie sich nicht wesentlich von malloc(). Obwohl es ziemlich ungewöhnlich ist, wenn Sie nicht so etwas wie Ihren eigenen Container schreiben, können Sie den Operator new direkt anrufen, wie zum Beispiel:

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

Es ist auch möglich, Operatoren neu entweder global oder für eine bestimmte Klasse zu überladen. IIRC, die Unterschrift lautet:

void *operator new(size_t);

Wenn Sie einen neuen Operator (entweder global oder für eine Klasse) überladen, möchten / müssen Sie natürlich auch den passenden Operator delete überladen. Für das, was es wert ist, gibt es auch einen separaten Operator new [], der verwendet wird, um Speicher für Arrays zuzuweisen - aber Sie sind mit ziemlicher Sicherheit besser dran, das ganze Durcheinander vollständig zu ignorieren.

Mit dem neuen Operator erstellen Sie normalerweise ein Objekt aus dem freien Speicher:

my_class *x = new my_class(0);

Der Unterschied zwischen den beiden besteht darin, dass der Operator new nur Rohspeicher zuweist, sonst nichts. Der neue Operator verwendet zunächst den Operator new, um Speicher zuzuweisen. Anschließend ruft er den Konstruktor für den richtigen Objekttyp auf, sodass das Ergebnis ein reales Live-Objekt ist, das in diesem Speicher erstellt wurde. Wenn dieses Objekt andere Objekte enthält (entweder eingebettet oder als Basisklassen), werden diese Konstruktoren ebenfalls aufgerufen.

Jerry Sarg
quelle
18
+1 In Bezug auf eine andere Formulierung verwendet der Standard rundum neue Ausdrücke und nur einmal einen neuen Operator , um auf den Ort des Anrufs zu verweisen. Ich neige dazu, dasselbe zu tun: Operator neu für den Allokator und neuer Ausdruck für die Verwendung.
David Rodríguez - Dribeas
3
Ein neuer Ausdruck ist die ganze Phrase, die mit neu beginnt. Wie nennt man nur den "neuen" Teil davon? Wenn es falsch ist, diesen neuen Operator zu nennen, sollten wir nicht "sizeof" den sizeof-Operator oder & die Adresse des Operators (wenn er sich wie einer verhält) nennen.
Kaz
1
Nach Kaz 'Bemerkung sollte die Frage vielleicht wie folgt umformuliert werden: Was ist der Unterschied zwischen dem neuen Operator und dem neuen Operator des Operators? :)
CS
2
"operator new" vs "new keyword"
user997112
2
@antred: Du würdest das mit so etwas veröffentlichen operator delete(x);.
Jerry Coffin
35

"Betreiber neu"

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

"neuer Betreiber":

Foo* foo = new Foo();

In diesem Beispiel new Foo()AnrufeFoo::operator new()

Mit anderen Worten, "neuer Operator" ruft " operator new()" genau wie der + Operator aufoperator +()

Austin Hyde
quelle
13
newist kein Operator in C ++. sizeofist zum Beispiel ein Operator, aber newund deletesind es nicht. newund deletesind Schlüsselwörter und die syntaktischen Konstrukte, die diese Schlüsselwörter bilden, werden als neuer Ausdruck und Löschausdruck bezeichnet .
Am
2
Uh, wenn überhaupt, sizeofist das syntaktische Konstrukt, und newund deletesind beide gültig, legal, Überlastung-able Betreiber. Von allem , was ich gesehen, die ich je newund deletesind beide Operatoren. Siehe [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Austin Hyde
7
Falsch. Die offizielle C ++ - Terminologie ist die Terminologie, die durch die Sprachspezifikation definiert wird, nicht durch eine Website. In der Sprachspezifikation gibt es keinen Thermo wie "neuer Operator", aber einen Begriff wie " operator newFunktion". Auch hier sizeofwird explicilty als „Operator“ bezeichnet, während newund deletewerden nie als Betreiber genannt.
Am
6
AndreyT: Falsch. Der C ++ - Standard nennt 'new' einen Operator, siehe 13.5 / 1.
3
@AndreyT: Ich dachte, wie Sie, dieser neue Operator sei der Allokator und der neue Ausdruck die Verwendung. Ich habe überprüft und überprüft, dass in §5.3.4 / 3 der aktuelle Standard den Begriff neuer Operator verwendet . Später in §5.3.4 / 8 nennt es die Allokatorfunktionen als Operator neu und Operator neu []
David Rodríguez - Dribeas
22

Es folgt das Zitat aus einem effektiveren C ++ - Buch von Scott Meyers:

Der neue Operator ruft eine Funktion auf, um die erforderliche Speicherzuordnung durchzuführen, und Sie können diese Funktion umschreiben oder überladen, um ihr Verhalten zu ändern. Der Name der Funktion, die der neue Operator aufruft, um Speicher zuzuweisen, lautet operator new.

Naveen
quelle
7
Der Begriff wurde offensichtlich vom Autor des Buches erfunden (oder möglicherweise aus einer veralteten Quelle entlehnt). In der formalen C ++ - Nomenklatur gibt es keinen Begriff wie "neuer Operator".
Am
2
@AndreyT: Ich habe in C ++ 11 nach "new operator" gesucht und festgestellt, dass an vier Stellen darauf verwiesen wird. Insbesondere zwei Verweise auf den "Placement New Operator"
Mooing Duck
11

Es gibt keinen Unterschied zwischen "neuer Operator" und "neuer Operator". Beide beziehen sich auf dasselbe: die überladbare / austauschbare operator newFunktion, die normalerweise die Rohspeicherzuweisung für Objekte ausführt, die durch neue Ausdrücke erstellt wurden .

Beachten Sie auch, dass keiner der Begriffe in der Sprachspezifikation enthalten ist (die die definierende Quelle der offiziellen Terminologie ist).

Wenn Sie newin Ihrem Programm ein Objekt erstellen, wird es als neuer Ausdruck bezeichnet . Der neue Ausdruck besteht aus einem Schlüsselwort newund zusätzlichen syntaktischen Teilen, die durch die Grammatik definiert werden. Kein Teil der Syntax dieses Ausdrucks wird jemals als "Operator" bezeichnet.

Die Rohspeicherzuweisungsfunktion operator newwird offiziell nur als " operator newFunktion" bezeichnet. Beachten Sie, dass die Wörter operatorund newin dieser Reihenfolge nur zwei separate Schlüsselwörter in C ++ sind. Sie bilden keinen englischen Begriff "Operator neu". Nirgendwo in der Sprachspezifikation finden Sie Verweise auf "operator new" als englischen Begriff. Jedes Mal ist dies nur eine Kombination aus zwei unabhängigen Schlüsselwörtern, die eine Deklarationssyntax für eine Speicherzuweisungsfunktion erzeugen.

Nochmals im Lebenslauf: Formal gibt es in C ++ keine englischsprachigen Begriffe wie "Operator neu" oder "neuer Operator". Die erstere Sequenz ist in der Sprachspezifikation als bloße Kombination von Schlüsselwörtern vorhanden, nicht als englischer Begriff. Letzteres ist überhaupt nicht vorhanden.

Ameise
quelle
14
Sie scheinen in einer pedantischen mentalen Masturbation verloren zu sein. Der Standard ist an einigen Stellen vage, und dies ist einer von ihnen. Es ist genauso sinnvoll, "den neuen Operator zu diskutieren" wie "den Plus-Operator zu diskutieren" oder "den + -Operator zu diskutieren".
7

Wenn Sie ein neues Objekt erstellen, wird der Speicher mit dem Operator new zugewiesen , und der Konstruktor wird aufgerufen, um den Speicher zu initialisieren . Der neue Operator führt sowohl die Zuordnung als auch die Initialisierung durch, wobei der neue Operator nur die Zuordnung vornimmt.

Chris Fulstow
quelle
6

Die Frage des OP ist nicht richtig formuliert. Es ist besser, als "Unterschied zwischen" Operator neu "und" neuer Ausdruck "zu phasen?" Hinweis "Operator neu" bezieht sich häufig auch auf "Operator neue Funktion".

Und es gibt viele richtige Antworten, unten ist meine:

1> 'neuer Ausdruck' ruft 'Operator neu' auf, um Rohspeicher zuzuweisen, und ruft dann den Konstruktor auf

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

2> 'operator new' weist nur Rohspeicher zu, kein großer Unterschied zu malloc

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

Der neue Operator : C ++ unterstützt die dynamische Zuordnung von Objekten mit dem neuen Operator. Der neue Operator reserviert Speicher für Objekte aus einem Pool, der als freier Speicher bezeichnet wird. Der neue Operator ruft den Sonderfunktionsoperator new auf.

operator new : Wenn die Anforderung null Byte Speicherplatz enthält, gibt operator new einen Zeiger auf ein bestimmtes Objekt zurück (dh wiederholte Aufrufe von operator new geben unterschiedliche Zeiger zurück). Wenn nicht genügend Speicher für die Zuordnungsanforderung vorhanden ist, gibt der Operator new NULL zurück oder löst eine Ausnahme aus. Das erste Argument für den Operator new muss vom Typ size_t sein (ein in STDDEF.H definierter Typ), und der Rückgabetyp ist immer ungültig *.

Hier ist ein MSDN-Link für weitere Details:

Der Bediener neue Funktion

Der neue Operator

aJ.
quelle
1
Leichte Klarstellung: Der neue Nicht-Platzierungsoperator muss immer einen Zuordnungsfehler auslösen (gemäß Standard). und Platzierungsformulare, wie z. B. ::new(std::nothrow), können beides (dieses spezielle Beispiel gibt einen Nullzeiger zurück).
1
  1. new ist sowohl ein Operator als auch ein Schlüsselwort.

    siehe [1] In 2.13 && In 2.12.

  2. new macht zwei Dinge: T * t = new T (arg);

    1) Speicher für das Objekt zuweisen: void * ptr = operator new (sizeof (T));

    // operator new ist eine Funktion (genau wie malloc in c), kein Operator (siehe [1] in 3.7.4). Aber Punkt 7 [2] sagte, es sei auch ein Operator. Meiner Meinung nach ist der Unterschied zwischen Operator und Funktion gering, und Sie können ihn sehen, wenn Sie sich daran erinnern, dass der Überladungsoperator durch Funktionen implementiert wird.

    // Wir können diesen Operator / diese Funktion (Operator neu) überladen und genau das tun, was wir wollen.

    2) Initialisieren Sie das Objekt im zugewiesenen Speicher: Rufen Sie T :: T (arg) auf ptr auf

    // Das kann nur der Compiler. Weder ich noch du können.

    // Auch der Compiler ruft die Konstruktoren der Mitgliedsobjekte und den Konstruktor der Basisklasse auf, wenn T sie hat. Und dieser Aufruf ist rekursiv. Das kann nur der Compiler.

  3. Operator new erledigt also einen Teil der Missionen von new, und nur in diesem Teil können wir etwas tun.

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

    [2]: Meyers, Scott. Effektives C ++, 3 ..

njuhgn
quelle