名前空間
変種
操作

delete 式

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (非推奨)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
delete
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

new 式によって以前に確保されたオブジェクトを破棄し、取得されたメモリ領域を解放します。

目次

[編集] 構文

::(オプション)    delete    expression (1)
::(オプション)    delete [] expression (2)
1) new 式によって作成された単一の非配列オブジェクトを破棄します。
2) new[] 式によって作成された配列を破棄します。

[編集] 説明

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およびそれ以降)
  • 型のアライメント要件が __STDCPP_DEFAULT_NEW_ALIGNMENT__ を越える場合は、アライメント対応の解放関数 (std::align_val_t 型の引数を取るもの) が優先されます。
  • それ以外の型の場合は、アライメント非対応の解放関数 (std::align_val_t 型の引数を取らない) が優先されます。
  • 優先される関数が複数見付かった場合は、次のステップで優先される関数のみが考慮されます。
  • 優先される関数が見付からなかった場合は、次のステップで優先されないものが考慮されます。
  • 残っている関数がひとつだけの場合は、その関数が選択されます。
(C++17およびそれ以降)
  • 見付かった解放関数がクラス固有の場合は、サイズ非対応のクラス固有の解放関数 (std::size_t 型の引数を取らない) が、サイズ対応のクラス固有の解放関数 (std::size_t 型の引数を取る) よりも優先されます。
  • そうでなければ、名前探索はグローバルスコープに到達し、
  • 型が完全である場合、かつ、 delete[] の場合に限り、被演算子が非トリビアルなデストラクタを持つクラス型またはその配列 (多次元でも良い) へのポインタの場合、サイズ対応のグローバルな関数 (std::size_t 型の引数を取る) が選択されます。
  • そうでなければ、グローバルなサイズ対応の解放関数 (std::size_t 型の引数を取る) とグローバルなサイズ非対応の解放関数 (std::size_t 型の引数を取らない) のどちらが選択されるかは未規定です。
(C++14およびそれ以降)

回収される記憶域のブロックへのポインタが、上記の処理によって選択された解放関数に第1引数として渡されます。 ブロックのサイズがオプショナルな std::size_t 引数として渡されます。 アライメント要件がオプショナルな std::align_val_t 引数として渡されます。 (C++17およびそれ以降)

expression がヌルポインタ値に評価された場合、デストラクタは呼ばれません。 解放関数は呼ばれるかもしれないし呼ばれないかもしれません (処理系定義です) が、デフォルトの解放関数はヌルポインタが渡されたとき何もしないことが保証されています。

(C++14以前)

expression がヌルポインタ値に評価された場合、デストラクタは呼ばれず、解放関数も呼ばれません。

(C++14およびそれ以降)

expressionnew で確保されたオブジェクトの基底クラスの部分オブジェクトへのポインタに評価された場合、その基底クラスのデストラクタは virtual でなければならず、そうでなければ動作は未定義です。

[編集] ノート

void へのポインタは、完全オブジェクト型へのポインタでないため、 delete できません。

キーワード delete に続く角括弧の組は常に delete の配列形式として解釈されるため、 delete の直後に空のキャプチャリストを持つラムダ式を書く場合は括弧で囲まなければなりません。

// delete []{return new int; }(); // パースエラー
delete ([]{return new int; })(); // OK
(C++11およびそれ以降)

[編集] キーワード

delete