new
Operator (C++)
Versucht, ein Objekt oder array von Objekten eines angegebenen oder Platzhaltertyps zuzuweisen und zu initialisieren, und gibt einen entsprechend typisierten, nichtzero-Zeiger auf das Objekt (oder auf das anfängliche Objekt des Arrays) zurück.
Syntax
new-expression
:
::
optnew
new-placement
optnew-type-id
new-initializer
opt
::
optnew
new-placement
opt(
type-id
)
new-initializer
opt
new-placement
:
(
expression-list
)
new-type-id
:
type-specifier-seq
new-declarator
opt
new-declarator
:
ptr-operator
new-declarator
opt
noptr-new-declarator
noptr-new-declarator
:
[
expression
]
attribute-specifier-seq
opt
noptr-new-declarator
[
constant-expression
]
attribute-specifier-seq
opt
new-initializer
:
(
expression-list
opt)
braced-init-list
Hinweise
Wenn dies nicht erfolgreich ist, new
wird null zurückgegeben oder eine Ausnahme ausgelöst. Weitere Informationen finden Sie unter The new
and delete
Operators. Sie können dieses Standardverhalten ändern, indem Sie eine benutzerdefinierte Ausnahmebehandlungsroutine schreiben und die _set_new_handler
Laufzeitbibliotheksfunktion mit dem Funktionsnamen als Argument aufrufen.
Informationen zum Erstellen eines Objekts im verwalteten Heap in C++/CLI und C++/CX finden Sie unter gcnew.
Hinweis
Microsoft C++-Komponentenerweiterungen (C++/CX) bieten Unterstützung für die new
Schlüsselwort (keyword) zum Hinzufügen von Vtable-Sloteinträgen. Weitere Informationen finden Sie unter new
(neuer Steckplatz in vtable)
Wenn new
zum Zuordnen des Speichers für ein C++-Klassenobjekt verwendet wird, wird der Konstruktor des Objekts aufgerufen, nachdem der Speicher zugewiesen wurde.
Verwenden Sie den delete
Operator, um den vom new
Operator zugewiesenen Speicher zuzuordnen. Verwenden Sie den delete[]
Operator, um ein vom new
Operator zugeordnetes Array zu löschen.
Im folgenden Beispiel wird ein zweidimensionales Array der Größe dim
durch 10 zugewiesen und dann freigegeben. Beim Zuweisen eines mehrdimensionalen Arrays müssen alle Dimensionen außer dem ersten konstanten Ausdruck sein, der zu positiven Werten ausgewertet wird. Die äußerst linke Arraydimension kann ein beliebiger Ausdruck sein, der zu einem positiven Wert ausgewertet wird. Beim Zuweisen eines Arrays mit dem new
Operator kann die erste Dimension null sein. Der new
Operator gibt einen eindeutigen Zeiger zurück.
char (*pchar)[10] = new char[dim][10];
delete [] pchar;
Die type-id
Deklarationen können weder Deklarationen noch Enumerationsdeklarationen enthaltenconst
volatile
. Der folgende Ausdruck ist unformiert:
volatile char *vch = new volatile char[20];
Der new
Operator weist keine Verweistypen zu, da sie keine Objekte sind.
Der new
Operator kann nicht zum Zuordnen einer Funktion verwendet werden, kann jedoch verwendet werden, um Zeigern funktionen zuzuweisen. Im folgenden Beispiel wird ein Array von sieben Zeigern auf Funktionen, die ganze Zahlen zurückgeben, zugewiesen und dann freigegeben.
int (**p) () = new (int (*[7]) ());
delete p;
Wenn Sie den Operator new
ohne zusätzliche Argumente verwenden und mit dem /GX
/EHa
, oder /EHs
der Option kompilieren, generiert der Compiler Code zum Aufrufen des Operatorsdelete
, wenn der Konstruktor eine Ausnahme auslöst.
In der folgenden Liste werden die Grammatikelemente von new
:
new-placement
Bietet eine Möglichkeit, zusätzliche Argumente zu übergeben, wenn Sie überladen new
.
type-id
Gibt den typ an, der zugewiesen werden soll; es kann sich um einen integrierten oder benutzerdefinierten Typ sein. Eine komplizierte Typspezifikation können Sie in Klammern einschließen, um die Reihenfolge der Bindung zu erzwingen. Der Typ kann ein Platzhalter (auto
) sein, dessen Typ vom Compiler bestimmt wird.
new-initializer
Stellt einen Wert für das initialisierte Objekt bereit. Initialisierer können für Arrays nicht angegeben werden. Der new
Operator erstellt Arrays von Objekten nur, wenn die Klasse über einen Standardkonstruktor verfügt.
noptr-new-declarator
Gibt die Grenzen eines Arrays an. Beim Zuweisen eines mehrdimensionalen Arrays müssen alle Dimensionen außer dem ersten konstanten Ausdruck sein, der zu positiven Werten ausgewertet wird, die in konvertierbar sind std::size_t
. Die äußerst linke Arraydimension kann ein beliebiger Ausdruck sein, der zu einem positiven Wert ausgewertet wird. Dies attribute-specifier-seq
gilt für den zugeordneten Arraytyp.
Beispiel: Zuweisen und Freigeben eines Zeichenarrays
Im folgenden Codebeispiel werden ein Zeichenarray und ein Objekt der Klasse CName
zugewiesen und dann wieder freigegeben.
// expre_new_Operator.cpp
// compile with: /EHsc
#include <string.h>
class CName {
public:
enum {
sizeOfBuffer = 256
};
char m_szFirst[sizeOfBuffer];
char m_szLast[sizeOfBuffer];
public:
void SetName(char* pszFirst, char* pszLast) {
strcpy_s(m_szFirst, sizeOfBuffer, pszFirst);
strcpy_s(m_szLast, sizeOfBuffer, pszLast);
}
};
int main() {
// Allocate memory for the array
char* pCharArray = new char[CName::sizeOfBuffer];
strcpy_s(pCharArray, CName::sizeOfBuffer, "Array of characters");
// Deallocate memory for the array
delete [] pCharArray;
pCharArray = NULL;
// Allocate memory for the object
CName* pName = new CName;
pName->SetName("Firstname", "Lastname");
// Deallocate memory for the object
delete pName;
pName = NULL;
}
Beispiel: new
Operator
Wenn Sie die Platzierungsform des new
Operators verwenden (das Formular mit mehr Argumenten als die Größe), unterstützt der Compiler keine Platzierungsform des delete
Operators, wenn der Konstruktor eine Ausnahme auslöst. Beispiel:
// expre_new_Operator2.cpp
// C2660 expected
class A {
public:
A(int) { throw "Fail!"; }
};
void F(void) {
try {
// heap memory pointed to by pa1 will be deallocated
// by calling ::operator delete(void*).
A* pa1 = new A(10);
} catch (...) {
}
try {
// This will call ::operator new(size_t, char*, int).
// When A::A(int) does a throw, we should call
// ::operator delete(void*, char*, int) to deallocate
// the memory pointed to by pa2. Since
// ::operator delete(void*, char*, int) has not been implemented,
// memory will be leaked when the deallocation can't occur.
A* pa2 = new(__FILE__, __LINE__) A(20);
} catch (...) {
}
}
int main() {
A a;
}
Initialisieren von Objekten, die zugeordnet sind new
Ein optionales new-initializer
Feld ist in der Grammatik für den new
Operator enthalten. Mit diesem Feld können neue Objekte mit benutzerdefinierten Konstruktoren initialisiert werden. Weitere Informationen dazu, wie die Initialisierung erfolgt, finden Sie unter Initialisierer. Das folgende Beispiel veranschaulicht die Verwendung eines Initialisierungsausdrucks mit dem new
Operator:
// expre_Initializing_Objects_Allocated_with_new.cpp
class Acct
{
public:
// Define default constructor and a constructor that accepts
// an initial balance.
Acct() { balance = 0.0; }
Acct( double init_balance ) { balance = init_balance; }
private:
double balance;
};
int main()
{
Acct *CheckingAcct = new Acct;
Acct *SavingsAcct = new Acct ( 34.98 );
double *HowMuch = new double { 43.0 };
// ...
}
In diesem Beispiel wird das Objekt CheckingAcct
mithilfe des new
Operators zugewiesen, es wird jedoch keine Standardinitialisierung angegeben. Der Standardkonstruktor für die Klasse Acct()
wird also aufgerufen. Anschließend wird das Objekt SavingsAcct
auf die gleiche Weise zugewiesen, mit der Ausnahme, dass es explizit auf 34.98 initialisiert wird. Da 34.98 vom Typ double
ist, wird der Konstruktor, der ein Argument dieses Typs verwendet, aufgerufen, um die Initialisierung zu behandeln. Schließlich wird der Nicht-Klassentyp HowMuch
auf 43.0 initialisiert.
Wenn ein Objekt einen Klassentyp aufweist und diese Klasse Konstruktoren hat (wie im vorherigen Beispiel), kann das Objekt vom new
Operator nur initialisiert werden, wenn eine dieser Bedingungen erfüllt ist:
Die im Initialisierer angegebenen Argumente stimmen mit den Argumenten eines Konstruktors überein.
Die Klasse verfügt über einen Standardkonstruktor (einen Konstruktor, der ohne Argumente aufgerufen werden kann).
Die explizite Initialisierung pro Element kann nicht ausgeführt werden, wenn Arrays mithilfe des new
Operators zugewiesen werden. Nur der Standardkonstruktor, falls vorhanden, wird aufgerufen. Weitere Informationen finden Sie unter Standardargumente.
Wenn die Speicherzuweisung fehlschlägt (operator new
gibt den Wert 0 zurück), erfolgt keine Initialisierung. Dieses Verhalten schützt vor Versuchen, Daten zu initialisieren, die nicht vorhanden sind.
Wie bei Funktionsaufrufen wird die Reihenfolge, in der initialisierte Ausdrücke ausgewertet werden, nicht definiert. Darüber hinaus sollten Sie sich nicht darauf verlassen, dass diese Ausdrücke vollständig ausgewertet werden, bevor die Speicherzuweisung erfolgt. Wenn die Speicherzuweisung fehlschlägt und der new
Operator null zurückgibt, werden einige Ausdrücke im Initialisierer möglicherweise nicht vollständig ausgewertet.
Lebensdauer der zugeordneten Objekte new
Objekte, die dem new
Operator zugeordnet sind, werden nicht zerstört, wenn der Bereich, in dem sie definiert sind, beendet wird. Da der new
Operator einen Zeiger auf die objekte zurückgibt, die er zuweist, muss das Programm einen Zeiger mit geeignetem Bereich definieren, um auf diese Objekte zuzugreifen und sie zu löschen. Beispiel:
// expre_Lifetime_of_Objects_Allocated_with_new.cpp
// C2541 expected
int main()
{
// Use new operator to allocate an array of 20 characters.
char *AnArray = new char[20];
for( int i = 0; i < 20; ++i )
{
// On the first iteration of the loop, allocate
// another array of 20 characters.
if( i == 0 )
{
char *AnotherArray = new char[20];
}
}
delete [] AnotherArray; // Error: pointer out of scope.
delete [] AnArray; // OK: pointer still in scope.
}
Sobald der Zeiger AnotherArray
den Gültigkeitsbereich in dem Beispiel verlässt, kann das Objekt nicht mehr gelöscht werden.
Funktionsweise von new
Der new-expression
(Ausdruck, der den new
Operator enthält) führt drei Dinge aus:
Sucht und reserviert Speicher für das zuzuweisende Objekt bzw. die zuzuweisenden Objekte. Wenn diese Phase abgeschlossen ist, wird der richtige Speicherplatz zugewiesen, aber es ist noch kein Objekt.
Initialisiert das/die Objekt(e). Sobald die Initialisierung abgeschlossen wurde, sind genügend Informationen vorhanden, damit der zugeordnete Speicher ein Objekt sein kann.
Gibt einen Zeiger auf die Objekte eines zeigertyps zurück, der von
new-type-id
odertype-id
. Das Programm verwendet diesen Zeiger, um auf das neu zugeordnete Objekt zuzugreifen.
Der new
Operator ruft die Funktion operator new
auf. Für Arrays eines beliebigen Typs und für Objekte, die keine class
, struct
oder union
Typen sind, wird eine globale Funktion aufgerufen, ::operator new
um Speicher zuzuweisen. Klassentypobjekte können ihre eigene operator new
statische Memberfunktion pro Klasse definieren.
Wenn der Compiler auf den new
Operator trifft, um ein Objekt vom Typ T
zuzuweisen, gibt er einen Aufruf T::operator new( sizeof(T) )
aus oder, wenn kein benutzerdefinierter operator new
Definiert ist. ::operator new( sizeof(T) )
So kann der new
Operator die richtige Speichermenge für das Objekt zuordnen.
Hinweis
Das argument ist operator new
vom Typ std::size_t
. Dieser Typ wird in direct.h, <malloc.h>>, <memory.h>, <search.h>, <stddef.h>, <stdio.h>, <stdlib.h, <string.h>> und <time.h> definiert.<
Eine Option in der Grammatik ermöglicht die Spezifikation ( new-placement
siehe Grammatik für new
Operator). Der Parameter kann nur für benutzerdefinierte Implementierungen operator new
verwendet werden. Er new-placement
ermöglicht es, zusätzliche Informationen an operator new
. Ein Ausdruck mit einem new-placement
Feld, z T *TObject = new ( 0x0040 ) T;
. B. wird übersetzt, T *TObject = T::operator new( sizeof( T ), 0x0040 );
wenn Klasse T Member operator new
hat, andernfalls in T *TObject = ::operator new( sizeof( T ), 0x0040 );
.
Die ursprüngliche Absicht des new-placement
Felds bestand in der Möglichkeit, hardwareabhängige Objekte an benutzerdefinierten Adressen zuzuordnen.
Hinweis
Obwohl im vorherigen Beispiel nur ein Argument im new-placement
Feld angezeigt wird, gibt es keine Einschränkung, wie viele zusätzliche Argumente auf diese Weise übergeben operator new
werden können.
Auch wenn operator new
für einen Klassentyp T
definiert wurde, können Sie den globalen Operator new
explizit verwenden, wie in diesem Beispiel:
T *TObject = ::new TObject;
Der Bereichsauflösungsoperator (::
) erzwingt die Verwendung des globalen new
Operators.
Siehe auch
Ausdrücke mit unären Operatoren
Schlüsselwörter
new
und delete
Operatoren
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für