3

shared_ptr スマート ポインターでは、参照カウントが使用されます。ただし、参照カウントには問題があり、参照のサイクルを壊すことはできません。

この問題について 4 つの質問があります。

1) 参照のサイクルが発生したスニペットを 1 つ提供してもらえますか?

2) 参照の循環を断ち切ることができない場合、RCSP はどのようにリソース管理の成功を保証しますか? サードパーティ製品でサイクルを断ち切る方法はありますか?

3)参照のサイクルを回避する方法はありますか?

4) 他のスマートポインタはどうですか? 彼らはソース管理をどのように処理しますか? たとえば、share_ptr、scope_ptr?

どうもありがとう!

4

2 に答える 2

11

サイクルを回避する通常の方法は、サイクルの任意の1つのポイントで弱参照を使用することです。この目的のために設計されshared_ptrたコンパニオンタイプがあります。weak_ptr

サイクルのどの部分を弱めるかは、設計の問題です。「親」オブジェクトが「子」を所有する設計では、親から子への参照は強く(shared_ptr)、子から親への参照は弱くする必要があります(weak_ptr)。

于 2010-02-27T00:47:44.950 に答える
7

サイクルを含む実用的な用途は、かなりの数の種類のグラフです。些細なスニペット (実際には起こりそうにないことですが) は次のようになります。

struct node {
    node *next;
};

int create_cycle() {
    node *a = new node;
    a.next = a;
}

create_cycle が戻った後、割り当てたばかりのノードにはそれ自体への参照が含まれていますが、他にポイントがないため、ガベージであっても参照カウンターはそれを収集しません。

Chris Jester-Young は、実用的な観点から、スマート ポインターを使用したサイクル ブレークを既に扱っています。ただし、内部でどのように機能するかについては、実際の詳細には触れませんでした。

weak_ptr は、一種の二重間接ポインターです。つまり、weak_ptr はオブジェクトに直接アクセスできません。代わりに、オブジェクトに到達するには、weak_ptr を shared_ptr に変換し、それを使用してオブジェクトに到達する必要があります。管理対象オブジェクト (そのため、オブジェクトの参照カウントはゼロではなく、まだ存在しています)。

そのため、weak_ptr は、オブジェクトが存在する限りオブジェクトへのアクセスを提供しますが、オブジェクトが存在しなくなったことを「認識」し、オブジェクトが存在していた (現在は解放された) メモリへのアクセスを提供しません。破壊されました。

サイクルの回避は、作業している物の種類によって異なります。グラフを頻繁に扱う場合 (一例として)、モデル化する対象のかなりの数にサイクルがあるため、グラフを回避することはほとんど不可能です。それ以外の場合は...場合によって異なります。かなりの数の開発者が、サイクルを含むリンクされた構造を作成する必要なしにキャリア全体を終えたと思います。平均的な週に数回行う人もいるでしょう。

他のスマート ポインターに関する限り、上記のように、weak_ptr 型は shared_ptr と連携して機能します。weak_ptr を使用しなくても shared_ptr を使用できますが、weak_ptr を実際に使用するには、ある時点でそれを shared_ptr に変換する必要があります。

于 2010-02-27T03:45:47.320 に答える