Namespaces
Variants

delete expression

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
delete expression
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Zerstört Objekt(e), die zuvor durch den new-expression allokiert wurden, und gibt den bezogenen Speicherbereich frei.

Inhaltsverzeichnis

Syntax

:: (optional) delete Ausdruck (1)
:: (optional) delete[] Ausdruck (2)
expression - eines der folgenden:
1) Zerstört ein einzelnes, nicht als Array erstelltes Objekt, das durch einen new-expression erzeugt wurde.
2) Zerstört ein Array, das durch einen new[]-Ausdruck erstellt wurde.

Erklärung

Gegeben sei der Zeiger, ausgewertet aus expression (nach möglichen Konvertierungen) als ptr .

1) ptr muss einer der folgenden sein:
  • ein Nullzeiger,
  • ein Zeiger auf ein Nicht-Array-Objekt, das durch einen new-expression erstellt wurde, oder
  • ein Zeiger auf ein Basis-Subobjekt eines Nicht-Array-Objekts, das durch einen new-expression erstellt wurde.
Der referenzierte Typ von ptr muss ähnlich zum Typ des Objekts (oder eines Basis-Subobjekts) sein. Wenn ptr etwas anderes ist, einschließlich wenn es sich um einen Zeiger handelt, der durch die Array-Form des new-Ausdrucks erhalten wurde, ist das Verhalten undefiniert .
2) ptr muss ein Nullzeiger oder ein Zeiger sein, dessen Wert zuvor durch eine Array-Form von new-expression erhalten wurde, deren allocation function keine nicht-allozierende Form war (d.h. Überladung (10) ).
Der referenzierte Typ von ptr muss ähnlich zum Elementtyp des Array-Objekts sein. Wenn ptr etwas anderes ist, einschließlich wenn es sich um einen Zeiger handelt, der durch die Nicht-Array-Form von new-expression erhalten wurde, ist das Verhalten undefiniert .

Das Ergebnis des delete-Ausdrucks hat immer den Typ void .

Wenn das zu löschende Objekt zum Zeitpunkt der Löschung einen unvollständigen Klassentyp hat, und die vollständige Klasse einen nicht-trivialen Destruktor oder eine Deallokationsfunktion besitzt, ist das Verhalten undefiniert (bis C++26) ist das Programm fehlerhaft (seit C++26) .

Wenn ptr kein Nullzeiger ist und die Deallocation-Funktion kein destroying delete ist (seit C++20) , ruft der delete-Ausdruck den Destruktor (falls vorhanden) für das Objekt auf, das zerstört wird, oder für jedes Element des zerstörten Arrays (fortschreitend vom letzten zum ersten Element des Arrays). Der Destruktor muss zugreifbar von der Stelle sein, an der der delete-Ausdruck erscheint.

Danach, unabhängig davon, ob eine Ausnahme von einem Destruktor geworfen wurde, ruft der delete-Ausdruck die Deallocation-Funktion auf: entweder operator delete (erste Version) oder operator delete [ ] (zweite Version) , es sei denn, der passende new-Ausdruck wurde mit einem anderen new-Ausdruck kombiniert (since C++14) .

Der Name der Freigabefunktion wird gesucht im Gültigkeitsbereich des dynamischen Typs des Objekts, auf das ptr zeigt, was bedeutet, dass klassen-spezifische Freigabefunktionen, falls vorhanden, vor den globalen gefunden werden. Wenn :: im Delete-Ausdruck vorhanden ist, wird nur der globale Namensraum durch diese Suche untersucht. In jedem Fall werden alle Deklarationen außer denen der üblichen Freigabefunktionen verworfen.

Falls eine Freigabefunktion gefunden wird, wird die aufzurufende Funktion wie folgt ausgewählt (siehe Freigabefunktion für eine detailliertere Beschreibung dieser Funktionen und ihrer Auswirkungen):

  • Wenn mindestens eine der Freigabefunktionen ein zerstörender Delete ist, werden alle nicht-zerstörenden Deletes ignoriert.
(since C++20)
  • Wenn die Ausrichtungsanforderung des Typs __STDCPP_DEFAULT_NEW_ALIGNMENT__ überschreitet, werden ausrichtungsbewusste Freigabefunktionen (mit einem Parameter vom Typ std::align_val_t ) bevorzugt. Für andere Typen werden die ausrichtungsunbewussten Freigabefunktionen (ohne Parameter vom Typ std::align_val_t ) bevorzugt.
  • Wenn mehr als eine bevorzugte Funktion gefunden wird, werden im nächsten Schritt nur bevorzugte Funktionen berücksichtigt.
  • Wenn keine bevorzugten Funktionen gefunden werden, werden die nicht-bevorzugten im nächsten Schritt berücksichtigt.
  • Wenn nur eine Funktion übrig bleibt, wird diese Funktion ausgewählt.
(since C++17)
  • Wenn die gefundenen Freigabefunktionen klassen-spezifisch sind, wird die größenunabhängige klassen-spezifische Freigabefunktion (ohne einen Parameter vom Typ std::size_t ) gegenüber der größenabhängigen klassen-spezifischen Freigabefunktion (mit einem Parameter vom Typ std::size_t ) bevorzugt.
  • Andernfalls erreicht die Suche den globalen Gültigkeitsbereich, und:
  • Wenn der Typ vollständig ist und, nur für die Array-Form, der Operand ein Zeiger auf einen Klassentyp mit einem nicht-trivialen Destruktor oder ein (möglicherweise mehrdimensionales) Array davon ist, wird die globale größenbewusste globale Funktion (mit einem Parameter vom Typ std::size_t ) ausgewählt.
  • Andernfalls ist es nicht spezifiziert, ob die globale größenbewusste Freigabefunktion (mit einem Parameter vom Typ std::size_t ) oder die globale größenunbewusste Freigabefunktion (ohne einen Parameter vom Typ std::size_t ) ausgewählt wird.
(seit C++14)

Die ausgewählte Freigabefunktion muss zugreifbar sein von dem Punkt aus, an dem der Delete-Ausdruck erscheint, es sei denn, die Freigabefunktion wird am Punkt der Definition des dynamischen Typs ’s virtuellen Destruktors ausgewählt.

Der Zeiger auf den zu löschenden Speicherblock wird der Deallokationsfunktion als erstes Argument übergeben, die durch den obigen Prozess ausgewählt wurde. Die Größe des Blocks wird als optionales std::size_t Argument übergeben. Die Ausrichtungsanforderung wird als optionales std::align_val_t Argument übergeben. (seit C++17)

Wenn ptr ein Nullzeigerwert ist, werden keine Destruktoren aufgerufen, und die Freigabefunktion kann aufgerufen werden oder auch nicht (es ist nicht spezifiziert), aber die standardmäßigen Freigabefunktionen garantieren, dass sie nichts tun, wenn ein Nullzeiger übergeben wird.

Wenn ptr ein Zeiger auf ein Basisklassen-Subobjekt des Objekts ist, das mit new allokiert wurde, muss der Destruktor der Basisklasse virtual sein, andernfalls ist das Verhalten undefiniert.

Hinweise

Ein Zeiger auf void kann nicht gelöscht werden, da es kein Zeiger auf einen Objekttyp ist.

Da ein Klammernpaar nach dem Schlüsselwort delete stets als Array-Form eines Delete-Ausdrucks interpretiert wird, muss ein Lambda-Ausdruck mit einer leeren Erfassungsliste unmittelbar nach delete in Klammern eingeschlossen werden.

// delete []{ return new int; }(); // parse error
delete ([]{ return new int; })();  // OK
(seit C++11)

Schlüsselwörter

delete

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
CWG 288 C++98 für die erste Form wurde der statische Typ des
Operanden mit seinem dynamischen Typ verglichen
vergleiche den statischen Typ des zu löschenden
Objekts mit seinem dynamischen Typ
CWG 353 C++98 ob die Freigabefunktion aufgerufen wird, wenn
der Destruktor eine Exception wirft, war nicht spezifiziert
immer aufgerufen
CWG 599 C++98 die erste Form konnte einen Nullzeiger jedes
Typs annehmen, einschließlich Funktionszeigern
außer Zeigern auf Objekttypen,
werden alle anderen Zeigertypen abgelehnt
CWG 1642 C++98 expression konnte ein Zeiger-Lvalue sein nicht erlaubt
CWG 2474 C++98 das Löschen eines Zeigers auf ein Objekt eines ähnlichen aber
unterschiedlichen Typs führte zu undefiniertem Verhalten
als wohldefiniert festgelegt
CWG 2624 C++98 Zeiger, die von nicht-allozierendem
operator new [ ] erhalten wurden, konnten an delete [ ] übergeben werden
verboten
CWG 2758 C++98 es war unklar, wie die Zugriffskontrolle für
die Freigabefunktion und den Destruktor durchgeführt wurde
klargestellt

Siehe auch