名前空間
変種
操作

delete式

From cppreference.com
< cpp‎ | language
 
 
C++言語
全般
フロー制御
条件実行文
if
繰り返し文 (ループ)
for
範囲for (C++11)
ジャンプ文
関数
関数宣言
ラムダ式
inline指定子
動的例外仕様 (C++17まで*)
noexcept指定子 (C++11)
例外
名前空間
指定子
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点数
文字 - 文字列 - nullptr (C++11)
ユーザー定義 (C++11)
ユーティリティ
属性 (C++11)
typedef宣言
型エイリアス宣言 (C++11)
キャスト
メモリ確保
delete
クラス
クラス固有の関数プロパティ
explicit (C++11)
static

特殊メンバ関数
テンプレート
その他
 
 

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

目次

[編集] 構文

::(オプション) delete   (1)
::(オプション) delete[] (2)
- 以下のいずれか
  • クラス型の式(オブジェクトへのポインタに文脈的に暗黙変換可能)
  • オブジェクト型へのポインタのprvalue
1) `new`式によって作成された単一の非配列オブジェクトを破棄します。
2) `new[]`式によって作成された配列を破棄します。

[編集] 説明

(可能な変換の後)expressionから評価されたポインタをptrとして与えます。

1) ptrは以下のいずれかでなければなりません。
  • ヌルポインタ、
  • `new`式によって作成された非配列オブジェクトへのポインタ、または
  • `new`式によって作成された非配列オブジェクトの基底サブオブジェクトへのポインタ。
ptrの指す型は、オブジェクトの型(または基底サブオブジェクトの型)と「類似」している必要があります。ptrがそれ以外の場合(配列形式の`new`式から得られたポインタを含む)は、動作は未定義です。
2) ptrはヌルポインタ、またはその値が以前に`new`式の配列形式によって取得されたポインタで、そのアロケーション関数が非アロケーション形式(すなわちオーバーロード(10))ではなかったものでなければなりません。
ptrの指す型は、配列オブジェクトの要素型と「類似」している必要があります。ptrがそれ以外の場合(`new`式の非配列形式から得られたポインタを含む)は、動作は未定義です。

delete式の結果は常に`void`型になります。

削除されるオブジェクトが削除時に不完全なクラス型である場合、(C++26まで)完全なクラスが非自明なデストラクタまたはデアロケーション関数を持つ場合、動作は未定義です。(C++26以降)プログラムはill-formed(不正な形式)になります。

ptrがヌルポインタでなく、(C++20以降)対応する`new`式が非破棄deleteではない場合、delete式は、破棄されるオブジェクトのデストラクタ(存在する場合)、または破棄される配列の各要素(配列の最後の要素から最初の要素へ進む)のデストラクタを呼び出します。デストラクタは、delete式が現れる場所からアクセス可能でなければなりません。

デストラクタによって例外がスローされたかどうかにかかわらず、delete式は、アロケーション関数が結合された`new`式でなかった場合を除き、`operator delete`(第1版)または`operator delete[]`(第2版)を呼び出します。

デアロケーション関数の名前は、ptrが指すオブジェクトの動的型のスコープで検索されます。これにより、クラス固有のデアロケーション関数が存在する場合は、グローバル関数より前に見つかります。delete式に`::`が含まれている場合、この検索ではグローバル名前空間のみが調べられます。いずれの場合も、通常のデアロケーション関数以外の宣言は破棄されます。

デアロケーション関数が1つ以上見つかった場合、呼び出される関数は次のように選択されます(これらの関数とその効果の詳細については、デアロケーション関数を参照してください)。

  • デアロケーション関数のうち少なくとも1つが破壊deleteである場合、すべての非破壊deleteは無視されます。
(C++20以降)
  • 型の配置要件が__STDCPP_DEFAULT_NEW_ALIGNMENT__を超える場合、配置を認識するデアロケーション関数(`std::align_val_t`型のパラメータを持つ)が優先されます。その他の型については、配置を認識しないデアロケーション関数(`std::align_val_t`型のパラメータを持たない)が優先されます。
  • 複数の優先関数が見つかった場合、次のステップでは優先関数のみが考慮されます。
  • 優先関数が見つからなかった場合、次のステップでは非優先関数が考慮されます。
  • 関数が1つだけ残った場合、その関数が選択されます。
(C++17以降)
  • 見つかったデアロケーション関数がクラス固有の場合、サイズを認識しないクラス固有のデアロケーション関数(`std::size_t`型のパラメータを持たない)が、サイズを認識するクラス固有のデアロケーション関数(`std::size_t`型のパラメータを持つ)より優先されます。
  • それ以外の場合、検索はグローバルスコープに達し、
  • 型が完全であり、かつ配列形式の場合のみ、オペランドが非自明なデストラクタを持つクラス型またはその(多次元を含む)配列へのポインタである場合、グローバルでサイズを認識するグローバル関数(`std::size_t`型のパラメータを持つ)が選択されます。
  • それ以外の場合、グローバルでサイズを認識するデアロケーション関数(`std::size_t`型のパラメータを持つ)とグローバルでサイズを認識しないデアロケーション関数(`std::size_t`型のパラメータを持たない)のどちらが選択されるかは未規定です。
(C++14以降)

選択されたデアロケーション関数は、delete式が現れる場所からアクセス可能でなければなりません。ただし、デアロケーション関数が動的型の仮想デストラクタの定義場所で選択された場合は除きます。

再利用されるストレージブロックへのポインタは、上記のプロセスによって選択されたデアロケーション関数に最初の引数として渡されます。ブロックのサイズは、オプションの`std::size_t`引数として渡されます。(C++17以降)配置要件は、オプションの`std::align_val_t`引数として渡されます。

ptrがヌルポインタ値の場合、デストラクタは呼び出されず、デアロケーション関数は呼び出される場合も呼び出されない場合もあります(未規定)、ただしデフォルトのデアロケーション関数はヌルポインタが渡された場合に何も行わないことが保証されています。

ptrが`new`で割り当てられたオブジェクトの基底クラスサブオブジェクトへのポインタである場合、基底クラスのデストラクタは仮想である必要があります。そうでない場合、動作は未定義です。

[編集] 注釈

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

`delete`キーワードの後に続く角括弧のペアは常にdelete式の配列形式として解釈されるため、`delete`の直後の空のキャプチャリストを持つラムダ式は括弧で囲む必要があります。

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

[編集] キーワード

delete

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
CWG 288 C++98 第1の形式では、オペランドの静的型が動的型と比較されていました
削除されるオブジェクトの静的型
を動的型と比較する
削除されるオブジェクトの静的型
CWG 353 C++98 デストラクタが例外をスローした場合にデアロケーション関数が呼び出されるか
どうかは未規定でした
常に呼び出されます
CWG 599 C++98 第1の形式は、関数ポインタを含む
任意の型のヌルポインタを受け取ることができました
オブジェクト型へのポインタを除き、
それ以外のすべてのポインタ型は拒否されます
CWG 1642 C++98 expressionはポインタlvalueになり得ました 許可されなくなった。
CWG 2474 C++98 類似しているが異なる型のオブジェクトへのポインタを削除すると未定義の動作となりました
CWG 2624
符号ビットにシフトする動作は定義された
非アロケーション`operator new[]`から取得されたポインタを`delete[]`に渡すことができました C++98 非アロケーション
`operator new[]`を`delete[]`に渡すことができました
禁止された
CWG 2758 C++98 デアロケーション関数とデストラクタのアクセス制御がどのように行われるかが不明確でした
デアロケーション関数とデストラクタのアクセス制御
明確化された

[編集] 関連項目

English 日本語 中文(简体) 中文(繁體)