delete 式
new 式によって以前に確保されたオブジェクトを破棄し、取得されたメモリ領域を解放します。
目次 |
[編集]構文
:: (オプション) delete expression | (1) | ||||||||
:: (オプション) delete [] expression | (2) | ||||||||
[編集]説明
1つめの形式 (非配列) の場合、 expression はオブジェクト型へのポインタであるか、そのようなポインタに文脈的に暗黙に変換可能なクラス型でなければならず、その値はヌルであるか、 new 式によって作成された非配列オブジェクトへのポインタであるか、 new 式によって作成された非配列オブジェクトの基底部分オブジェクトへのポインタでなければなりません。 expression がそれ以外の場合 (配列形式の new 式によって取得したポインタである場合を含む)、動作は未定義です。
2つめの形式 (配列) の場合、 expression はヌルポインタ値であるか、配列形式の new 式によって以前に取得されたポインタ値でなければなりません。 expression がそれ以外の場合 (非配列形式の new 式によって取得されたポインタである場合を含む)、動作は未定義です。
式の結果は常に void 型です。
削除対象のオブジェクトが削除の時点で不完全クラス型であり、その完全クラスが非トリビアルなデストラクタか または解放関数を持つ場合、動作は未定義です。
expression がヌルポインタでないかつ解放関数が破棄削除形式でない(C++20以上)場合、 delete
式はその破棄対象のオブジェクトに対して、または破棄対象の配列のすべての要素に対して (配列の最後の要素から最初の要素の順で)、デストラクタを呼びます (もしあれば)。
その後、いずれかのデストラクタが例外を投げたかどうかにかかわらず、 delete 式は解放関数operator delete (1つめのバージョンの場合) または operator delete[] (2つめのバージョンの場合) を呼びます。 ただし対応する new 式が別の new 式と合成されている場合は除きます。(C++14以上)
解放関数は expression の指すオブジェクトの動的な型のスコープで名前探索されます。 これはクラス固有の解放関数 (もしあれば) がグローバルなものよりも前に見付かるという意味です。 delete
式に ::
が存在する場合は、この名前探索はグローバル名前空間のみを調べます。
名前探索が複数の解放関数を見付けた場合、呼ばれる関数は以下に従って選択されます (これらの関数およびその効果の詳細な説明はついては解放関数を参照してください)。
| (C++20以上) |
| (C++17以上) |
- 見付かった解放関数がクラス固有の場合は、サイズ非対応のクラス固有の解放関数 (std::size_t 型の引数を取らない) が、サイズ対応のクラス固有の解放関数 (std::size_t 型の引数を取る) よりも優先されます。
| (C++14以上) |
回収される記憶域のブロックへのポインタが、上記の処理によって選択された解放関数に第1引数として渡されます。 ブロックのサイズがオプショナルな std::size_t
引数として渡されます。 アライメント要件がオプショナルな std::align_val_t
引数として渡されます。(C++17以上)
expression がヌルポインタ値に評価された場合、デストラクタは呼ばれません。 解放関数は呼ばれるかもしれないし呼ばれないかもしれません (未規定)。 しかし、デフォルトの解放関数はヌルポインタが渡されたとき何もしないことが保証されています。
expression が new で確保されたオブジェクトの基底クラスの部分オブジェクトへのポインタに評価された場合、その基底クラスのデストラクタは virtual でなければならず、そうでなければ動作は未定義です。
[編集]ノート
void へのポインタは、完全オブジェクト型へのポインタでないため、 delete できません。
キーワード // delete []{return new int; }(); // パースエラー delete ([]{return new int;})();// OK | (C++11以上) |