しかし、その場合、もはや f はありません。
ポインターはスコープ外になりますが、それは本当ですが、指し示しf
たのと同じオブジェクトへのポインターをまだ返しています。f
したがって、そのオブジェクトへのハンドルがまだありdelete
、返されたポインターで呼び出すことができます。実際、でオブジェクトを作成した後はdelete
いつでも呼び出すことができますnew
。
気をつけなければならないことは、次のことです。
delete
実際に、割り当てられた各オブジェクトに対してある時点で呼び出しますnew
(そうしないと、メモリ リークが発生します)。
delete
同じオブジェクトに対して複数回呼び出さないでください。そうしないと、未定義の動作が発生します。
- 破棄されたオブジェクトを指すポインター (つまり、「ダングリング ポインター」) を逆参照しないでください。そうしないと、未定義の動作が発生します。
new
一般に、最新の C++ ではおよびを介した手動のメモリ管理delete
は推奨されておらず、代わりにスマート ポインターを使用して所有権ポリシーを実現する必要があります。また...
以下の4つの方法では、私たちがすべきことだけがより良いです
正確ではありません。実際、絶対にすべきではないと思いますが、所有する生のポインターではなく、スマート ポインターを作成して返すように modified のバージョンを実行することはできますbetter()
が。better()
ただし、機能mediocre()
は実際にはかなり優れており、それには次の 2 つの理由があります。
- まず第一に、コンパイラがコピー コンストラクターの呼び出しを省略して(名前付き) 戻り値の最適化を実行する可能性が非常に高いため、実行時のオーバーヘッドが発生しません。
- 第 2 に、C++11 の移動セマンティクスのおかげで、省略が実行されない場合でも、ほとんどの場合、値による戻りを効率的にする
Foo
移動コンストラクターを装備できるためです。
さらに、Zoidbergがコメントで正しく言及しているように、ポインターが本当に必要ない場合は、ポインターをまったく使用しないでください。一意の所有権は、多くの場合、自動ストレージ期間 (別名「スタック上」) を持つオブジェクトを作成することで実現でき、ムーブ セマンティクスはこのプラクティスを効率的にします。ポインターは、参照セマンティクスが必要な場合にのみ作成する必要があります。