1

私の理解によると、すべての shared_ptr オブジェクトを使用し、循環依存関係がある場合、循環依存問題に弱いポインターが使用されます。ウィーク ポインターは、サイクルを中断するために使用されます。弱いポインターは、共有ポインターを作成する lock() を使用してこれを実現します。

class A { shared_ptr<B> b; ... };
class B { weak_ptr<A>   a; ... };
shared_ptr<A> x(new A); // +1
x->b = new B;           // +1
x->b->a = x;            // No +1 here

しかし、x->b->a.lock() を呼び出してロックを作成したと仮定すると、x の参照カウントは 2 になり、x がスコープを離れてもメモリ リークが発生しますよね? lock() を使って共有ポインタを作成したところ、ref カウントが 2 になりました。私の理解が正しいかどうか教えてください。

4

1 に答える 1

3

共有オブジェクトには、次の2 つの異なる参照カウントが関係しています。shared_ptr

  • オブジェクト、つまりshared_ptrインスタンスへの参照の数。
  • コントロール ブロックへの参照の数、つまりshared_ptrweak_ptrインスタンス。

Aweak_ptrは後者のカウントにのみ寄与します。すべてのshared_ptrインスタンスが破棄されると、オブジェクト デリータが呼び出されます。これは通常、オブジェクトを破棄するデフォルトのデリータです。弱いポインターがある場合、制御ブロックは引き続き存在します。すべてのウィーク ポインターも破棄された場合は、制御ブロックが破棄されます。

そのため(各インスタンスでオブジェクトポインタを直接キャッシュする最適化の可能性を無視してshared_ptr)、あなたの場合x、インスタンスへのポインタを持つコントロールブロックを指しています(あなたのために隠されています)A。そしてb、インスタンスへのポインターを持つ 2 番目の制御ブロックを指しているそのインスタンスのメンバーがありBます。最後に、そのインスタンスには、xポイントする制御ブロックへのポインターがあります。これは、はい循環しますが、所有権の循環ではありません。

于 2014-03-06T00:43:44.707 に答える