回答:
Stroustrup自身が答えます。抜粋:
C ++では、削除の実装で明示的に左辺値のオペランドをゼロにすることが許可されており、実装でそれが実行されることを期待していましたが、そのアイデアは実装者に人気があるようには見えません。
しかし、彼が提起する主な問題は、削除の引数が左辺値である必要はないということです。
まず、nullに設定すると、メモリに格納された変数が必要になります。通常、変数にはポインタが含まれていますが、計算されたばかりのアドレスにあるオブジェクトを削除したい場合もあります。これは、「無効化」削除では不可能です。
次にパフォーマンスが始まります。削除が完了するとすぐにポインターがスコープから外れるようにコードを記述した可能性があります。nullで埋めるのは時間の無駄です。そしてC ++は「それを必要としないのか?それならあなたはそれにお金を払う必要がない」という思想を持つ言語です。
安全性が必要な場合は、サービスにさまざまなスマートポインタが用意されています。または、独自のポインタを作成することもできます。
delete (ptr + i)
そのメモリを指す複数のポインタを持つことができます。削除に指定したポインターがnullに設定されていても、他のすべてのポインターはnullに設定されていなかった場合、誤った安心感が生まれます。ポインタは、アドレス、数値にすぎません。逆参照操作を持つintの場合もあります。私の要点は、削除したばかりの同じメモリを参照しているポインターを見つけるために、すべてのポインターをスキャンし、それらもnullにする必要があるということです。言語がそのように設計されていないため、そのアドレスのすべてのポインタをスキャンしてそれらをnullにすることは、計算量が多いでしょう。(他のいくつかの言語は、異なる方法で同様の目標を達成するために参照を構成しますが)。
別の理由があります。deleteが引数をNULLに設定するとします。
int *foo = new int;
int *bar = foo;
delete foo;
バーをNULLに設定する必要がありますか?これを一般化できますか?
ポインターを自動的にNULLに設定しても、ポインターの使用法が悪い場合の問題のほとんどは解決されません。回避できる唯一のクラッシュは、2回削除しようとした場合です。そのようなポインターでメンバー関数を呼び出すとどうなりますか?それでもクラッシュします(メンバー変数にアクセスする場合)。C ++では、NULLポインターで関数を呼び出すことは制限されていません。また、パフォーマンスの観点からも制限されていません。
私はこの質問に奇妙な答えをする人々を見かけます。
ptr = NULL; このような単純なステートメントがパフォーマンスの遅延をどのように引き起こしますか?
別の答えは、同じメモリ位置を指す複数のポインタを持つことができるということです。確かにできます。この場合、1つのポインターに対する削除操作はそのポインターのみをNULLにし(削除がポインターをNULLにした場合)、他のポインターは非NULLであり、解放されているメモリー位置を指します。
これに対する解決策は、ユーザーが同じ場所を指すすべてのポインターを削除する必要があることでした。内部的には、メモリが解放されていないよりもすでに解放されているかどうかをチェックする必要があります。ポインタをNULLにするだけです。
Stroustrupは、このように機能するように削除を設計できたはずです。プログラマーがこれを処理するだろうと彼は思った。それで彼は無視した。