私の現在のプロジェクトでは、boost::shared_ptr
かなり広範囲に使用しています。
最近、私の仲間のチームメイトもを使い始めましweak_ptr
た。どちらをいつ使うかわかりません。
weak_ptr
これとは別に、に変換したい場合はどうすればよいですかshared_ptr
。ロックをオンにweak_ptr
して作成するとshared_ptr
、他のスレッドのコードに影響しますか?
私の現在のプロジェクトでは、boost::shared_ptr
かなり広範囲に使用しています。
最近、私の仲間のチームメイトもを使い始めましweak_ptr
た。どちらをいつ使うかわかりません。
weak_ptr
これとは別に、に変換したい場合はどうすればよいですかshared_ptr
。ロックをオンにweak_ptr
して作成するとshared_ptr
、他のスレッドのコードに影響しますか?
一般的および要約、
強力なポインタは、それ自体の有効性を保証します。たとえば、次の場合に使用します。
弱いポインタは、自身の有効性を知ることを保証します。たとえば、次の場合に使用します。
弱いポインタのLock()は、強いポインタを返します。これは、弱いポインタにアクセスする方法です。オブジェクトが無効になった場合(削除された場合など)、強力なポインターはNULLになります。それ以外の場合は、オブジェクトを指します。これを確認する必要があります。
このように設定されているため、オブジェクトを使用中に誤って削除することはありません。これは、一時的な(ローカルの)強力なポインターを作成したため、その強力なポインターが残っている間、オブジェクトの存在を保証するためです。オブジェクトの使用を終えたら、通常、強力なポインターをスコープから外します(または再割り当てします)。これにより、オブジェクトを削除できます。マルチスレッドの場合は、スレッドセーフが組み込まれていない他のものと同じように注意して扱ってください。マルチスレッドの場合は、上記の保証が適用されることに注意してください。AFAIK彼らはそれを超えて特別なことは何もしません。
ブースト共有ポインターには、ガベージコレクターのような機能もあります。これは、オブジェクトへの最後の強力なポインターがなくなるか、別の場所を指すと、オブジェクトが削除されるためです。
他の回答で言及されているパフォーマンスと循環依存関係もあります。
基本的に、ブースト共有ポインターライブラリを使用すると、プログラムの作成を台無しにすることはできませんが、ポインター、オブジェクトの所有権、および存続期間を適切に設計するために時間をかけることに代わるものではありません。そのような設計がある場合は、ライブラリを使用してそれを適用できます。そのような設計がない場合、以前とは異なる問題が発生する可能性があります。
weak_ptr
作成するオブジェクトに周期的な参照が含まれている場合、つまり自分自身に背を向けshared_ptr
ているオブジェクトへの参照がある場合に使用shared_ptr
します。これは、shared_ptr
循環参照を処理できないためです。両方のオブジェクトがスコープ外になると、相互参照はそれらが「ガベージコレクション」されないことを意味するため、メモリが失われ、メモリリークが発生します。は参照カウントを増加させないためweak_ptr
、循環参照の問題は発生しません。これはまた、一般的に、参照カウントされているものへのポインターを取得したいだけで、その参照カウントを増やしたくない場合は、を使用することを意味しますweak_ptr
。
それ以外の場合は、を使用できますshared_ptr
。
詳細については、Boostのドキュメントを確認してください。
共有ポインターは参照カウントを実装します。弱ポインターは参照カウントに影響しません。オブジェクトへの共有ポインターがない場合は、弱ポインターのみがオブジェクトを削除し、弱ポインターはオブジェクトが失われたことを通知します。
弱いポインタを使用する理由は2つあります。
したがって、一般的に、参照されるオブジェクトを削除させたいことがわかっていて、それを検出したい場合にのみ、弱ポインターを使用することをお勧めします。その他の場合は、共有ポインター(参照カウント)または直接ポインター、特にを使用します。オブジェクトが削除されないことがわかっている場合は、メソッドのローカル変数で。エラーが発生しやすくなりますが、共有ポインタよりも高速です。
NB循環オブジェクトは弱ポインターを必要としません。代わりに、最も適切に構築されたプログラムで、調理されていない通常のポインターを使用できます。ただし、弱いポインタはリスクが低くなります。
ガベージコレクターを実装しようとしているのでない限り、弱いポインターを使用しようとしないでください。これは、問題が発生する可能性のあるすべてのものを追跡するのが難しいため、C++ではホットなアイデアではありません。