4

弱いポインタを使用してアクセスする場合は、最初に、ロックして、ポイントされたオブジェクトへの強いポインタを取得することをお勧めします。ポイントしたオブジェクトが以前に削除された場合、ロックが成功しない場合があります。

弱いポインタを決定するためにサイクルを壊すのに何か間違ったことをしなければ、ロックは成功するように私には思えます。つまり、設計をクロスチェックするためだけにロックしているのです。

これは正しいです?

キャッシングについていくつかのコメントを見ましたが、weak_ptrsの悪用のようです。しかしもちろん、ある人の虐待は別の人の革新です。意見を聞きたいです。

4

4 に答える 4

3

それを「ロック」と考えるのではなく、所有権の別のシェアを取得するだけであることに注意してください。ウィークポインタ自体は何も所有していないため、直接使用することはできません。

弱ポインタ​​の一般的な使用法は、おそらく並行コードにあります。どこかに共有ポインタが所有するオブジェクトのコレクションがあるとします。次に、それらの同じオブジェクトを参照する弱いポインターの別のコレクション(タイマーのコレクションなど)を作成できます。2番目のスレッドは、弱いポインターを取得し、そこから共有ポインターを作成しようとします。呼び出しが成功すると、たとえば、オブジェクトのタイマールーチンが呼び出されます。その時点でタスクがすでに終了している場合、共有ポインターはnullになり、2番目のスレッドはタスクをスキップします。

についての重要な事実std::shared_ptrは、その内部参照カウントがアトミックに更新されるため、私が説明した方法でコードを記述でき、レースフリーになるということです。

Thread 1                          Thread 2
--------                          --------
std::set<std::shared_ptr<Task>>   std::list<std::weak_ptr<Task>> todo;
add
remove                            for (auto wp : todo)
                                      if (auto p = wp.lock())
                                          p->do_work();
于 2012-06-12T11:59:42.160 に答える
3

いいえ、すべきではありません。

オブザーバーのリストを維持していると仮定します。破棄すると、オブザーバーを監視対象のオブジェクトからサブスクライブ解除する必要がありますが、オブザーバーは監視対象のエンティティのリストを維持する必要があり、サイクルが発生します。

設計を単純化するために、あるレベルの間接参照を導入する方が簡単です。オブザーバーとエンティティの間のブローカーは、オブザーバーを破棄し、エンティティがその活性を照会できるようにします。

方法 ?単純にを割り当てstd::shared_ptr<Observer>て、エンティティにを保持させるだけで、std::weak_ptr<Observer>エンティティがオブザーバーのリストを反復処理するときに、最後の反復以降に死亡した人への参照を選別できます。

于 2012-06-12T12:11:40.220 に答える
2

サイクルを中断するためだけに使用している場合はweak_ptr、はい、それshared_ptrからの取得は常に成功するはずです。

しかし、それだけが用途ではありません。Matthieu M.は、それらを使用する1つの例を示しています。

キャッシングについておっしゃっていますweak_ptrが、これはサイクルがない場合の良いユースケースであり、私はそれを悪用とはまったく考えていません。システムの他の部分(別のスレッドまたはキャッシュ)が所有するオブジェクトがあり、後で使用できるようにそのオブジェクトへの参照を保存する場合shared_ptr、オブジェクトを参照するためにを使用する場合は、の所有権を共有します。それとその寿命を延ばします。後でオブジェクトが必要になるかどうかわからない場合は、オブジェクトの寿命を延ばしたくない場合は、を使用して、必要なときにオブジェクトがweak_ptrまだ存在するかどうかを確認できます。存在しない場合は、別のオブジェクトを見つけるか、再度作成します(データベースクエリが必要になるなど、時間がかかる場合があります。そのため、可能であれば既存のオブジェクトを再利用する必要があります)。

于 2012-06-12T12:34:44.427 に答える
0

が無効であるユースケースはweak_ptr、競合状態/設計不良のようです。

weak_ptrアクセスするオブジェクトが所有権を持たない、厳密なライフタイムを持つオブジェクトにアクセスするために使用する必要があります

ライフタイムが厳密でないオブジェクトがある場合は、を使用する必要がありますshared_ptr

于 2012-06-12T11:58:07.253 に答える