delete expression
以前 new式 によって割り当てられたオブジェクトを破棄し、取得したメモリ領域を解放します。
目次 |
構文
::
(オプション)
delete
式
|
(1) | ||||||||
::
(オプション)
delete[]
式
|
(2) | ||||||||
| expression | - |
以下のいずれか:
|
説明
expression から評価されたポインタ(変換が行われる可能性あり)を ptr として与えられた場合。
- ヌルポインタ
- new-expression によって作成された非配列オブジェクトへのポインタ
- new-expression によって作成された非配列オブジェクトの基底サブオブジェクトへのポインタ
delete式の結果の型は常に void です。
削除されるオブジェクトが不完全なクラス型である場合、 完全なクラスが非トリビアルなデストラクタまたは解放関数を持つとき、動作は未定義 (C++26まで) プログラムは不適格 (C++26以降) 。
ptr が null ポインタでない場合 かつ 解放関数 が destroying delete でない場合 (C++20以降) 、delete式は破棄されるオブジェクトの デストラクタ (存在する場合)、または破棄される配列の各要素のデストラクタ(配列の最後の要素から最初の要素に向かって順に)を呼び出す。デストラクタはdelete式が現れる位置から アクセス可能 でなければならない。
その後、例外がどのデストラクタによってスローされたかどうかに関わらず、delete式は デアロケーション関数 を呼び出します: operator delete (第1バージョン)または operator delete [ ] (第2バージョン)のいずれかです 、ただし、対応するnew式が別のnew式と組み合わされていた場合を除きます (since C++14) 。
デアロケーション関数の名前は、
ルックアップ
が
ptr
によって指されるオブジェクトの動的型のスコープで行われます。これは、クラス固有のデアロケーション関数が存在する場合、グローバルなものよりも先に見つかることを意味します。delete式に
::
が存在する場合、このルックアップではグローバル名前空間のみが調べられます。いずれの場合も、通常のデアロケーション関数以外の宣言は破棄されます。
いずれかの解放関数が見つかった場合、呼び出す関数は以下のように選択されます(これらの関数とその効果に関する詳細な説明については 解放関数 を参照してください):
|
(C++20以降) |
|
(C++17以降) |
- 見つかった解放関数がクラス固有の場合、サイズ非対応のクラス固有解放関数( std::size_t 型のパラメータを持たない)が、サイズ対応のクラス固有解放関数( std::size_t 型のパラメータを持つ)よりも優先されます。
|
(C++14以降) |
選択された解放関数は、解放関数が アクセス可能 でなければなりません。ただし、解放関数が 動的型 の 仮想デストラクタ の定義時点で選択される場合は除きます。
解放されるストレージブロックへのポインタは、上記のプロセスで選択された デアロケーション関数 に第一引数として渡されます。ブロックのサイズはオプションの std::size_t 引数として渡されます。 アライメント要件はオプションの std::align_val_t 引数として渡されます。 (C++17以降)
ptr がヌルポインタ値の場合、デストラクタは呼び出されず、解放関数が呼び出されるかどうかは規定されていないが、デフォルトの解放関数はヌルポインタが渡された場合に何も行わないことが保証されている。
ptr が new で確保されたオブジェクトの基底クラス部分オブジェクトへのポインタである場合、基底クラスのデストラクタは virtual でなければならず、そうでない場合の動作は未定義です。
注記
void へのポインタは、オブジェクト型へのポインタではないため削除できません。
|
// delete []{ return new int; }(); // 解析エラー delete ([]{ return new int; })(); // OK |
(C++11以降) |
キーワード
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用バージョン | 公開時の仕様 | 正しい仕様 |
|---|---|---|---|
| CWG 288 | C++98 |
最初の形式では、オペランドの静的型が
その動的型と比較されていた |
削除されるオブジェクトの静的型を
その動的型と比較する |
| CWG 353 | C++98 |
デストラクタが例外をスローした場合に
解放関数が呼び出されるかどうかが未規定 |
常に呼び出される |
| CWG 599 | C++98 |
最初の形式は関数ポインタを含む
あらゆる型のヌルポインタを扱えた |
オブジェクト型へのポインタを除く
他の全てのポインタ型は拒否される |
| CWG 1642 | C++98 | 式 がポインタ左辺値になり得た | 許可されない |
| CWG 2474 | C++98 |
類似しているが異なる型のオブジェクトへの
ポインタを削除すると未定義動作となった |
明確に定義された動作とする |
| CWG 2624 | C++98 |
非割り当て
operator new [ ] から取得したポインタを delete [ ] に渡せた |
禁止 |
| CWG 2758 | C++98 |
解放関数とデストラクタに対する
アクセス制御の方法が不明確だった |
明確化 |