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