web-dev-qa-db-ja.com

C ++ 11:所有していないすべてのrawポインターをstd :: shared_ptr()に置き換えますか?

_std::unique_ptr_の登場により、傷のついた_std::auto_ptr_をようやく休めるようになりました。そのため、過去数日間、スマートポインタを使用し、すべてのdeleteをコードから削除するようにコードを変更しています。

Valgrindは私のコードはメモリクリーンであると言っていますが、スマートポインタのセマンティックの豊富さにより、コードがよりクリーンで理解しやすくなります。

ほとんどのコードでは、変換は単純です。所有するオブジェクトが保持する生のポインタの代わりに_std::unique_ptr_を使用し、deleteを破棄して、慎重にget()を振ります。必要に応じて、reset()およびmove()を呼び出して、残りのコードと適切にインターフェースします。

私は非所有の生のポインタをスマートポインタに変換しているところです。

オブジェクトの存続期間に注意していたので(モジュールが一方向にのみ依存することを確認しています)、valgrindは、初期化されていない読み取り、ダングリングポインター、またはリークがないことを教えてくれます。したがって、技術的には、これらの所有していない生のポインタをそのままにしておくことができます。

ただし、オプションの1つは、これらの非所有rawポインターを_std::shared_ptr_に変更することです。または、生のポインタのままにしておく方が良いでしょうか?

スマートポインターのベテランユーザーから、どのような経験則を使用して非所有の生のポインターを保持するか、またはそれらを_std::shared_ptr_、に変換します。コードのユニットテストとvalgrindを常に行うことを覚えておいてください。

編集:_std::shared_ptr_の使用を誤解している可能性があります-_std::unique_ptr_と組み合わせて使用​​できますか、または_std::shared_ptr_を使用する場合、すべてのハンドルも_std::shared_ptr_?

57
kfmfe04

個人的には、これは私が(多かれ少なかれ)行う方法です:

  • nique_ptrsは唯一の所有権です
  • 生のポインタ生のポインタを私に与えた人は、そのオブジェクトの寿命が私の寿命と同じかそれ以上であることを保証します。
  • shared_ptrsは共有所有権用です
  • weak_ptrsは、システムがオブジェクトを使用する前に、そのオブジェクトがまだ存在するかどうかを確認する場合に使用します。システムがサブシステムのサブシステムを通過するすべてのオブジェクトの寿命を保証するようにシステムを設定するとクリーンになるため、これはコードではまれです(この場合、生のポインターを使用します)。

はるかに、私はshared_ptrsよりもunique_ptrsを多く使用し、ウィークポインターよりもrawポインターを使用しています。

104
David

リソースを所有する複数のものが必要な場合はshared_ptrを使用し(所有しているものが「ランダム」にスコープから出入りする場合があります)、単一のものがリソースを所有している場合はunique_ptrを使用し、参照するだけで所有しない場合の生のポインタ(この参照が、リソースが存在する期間より長く続くことはないと予想されます)。

4番目のタイプは、shared_ptrと呼ばれる、weak_ptrの生のポインタの一種です。これを使用して、実際には所有せずにshared_ptrを参照します。その後、オブジェクトがまだ存在するかどうかを確認して使用できます。

11
GManNickG

標準ライブラリで所有していない唯一のスマートポインタはstd::weak_ptrです。ただし、それを使用するには、実際に所有するオブジェクトが指示先をstd::shared_ptrに保持する必要があります。

以前にstd::unique_ptrを使用したと思います。これらを今すぐshared_ptrに変換すると、所有していないポインターが参照されていることを所有していないポインターが認識できるという利点がありますが、所有していないコンポーネントは、未所有のポインターがぶら下がったままにすることができます。これを検出します。ただし、shared_ptrunique_ptrよりも(非常に?)小さなパフォーマンスとメモリオーバーヘッドが発生します。

個人的には、1つのshared_ptrの代わりに1つのweak_ptrと多くのunique_ptrsを使用することをお勧めします。一般的なケースでは、多くのrawポインターを使用し、本当にパフォーマンスの問題がある場合はunique_ptrを使用します。

8
ltjax