delete expression
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:
|
Erklärung
Gegeben sei der Zeiger, ausgewertet aus expression (nach möglichen Konvertierungen) als ptr .
- 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.
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):
|
(since C++20) |
|
(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.
|
(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
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 |