24

shared_ptrは、Boostライブラリの参照カウントスマートポインタです。

参照カウントの問題は、サイクルを破棄できないことです。これをC++で解決するにはどうすればよいのでしょうか。

「サイクルを作成しない」、「weak_ptrを使用する」などの提案はしないでください。

編集

サイクルを作成することがわかっている場合は問題がないので、weak_ptrを使用するという提案は好きではありません。また、実行時にshared_ptrsを生成した場合、コンパイル時にサイクルが発生することもわかりません。

だから、私は特にそのような答えを持たないように頼んだので、weak_ptrを使用している答えを自己削除してください...

4

12 に答える 12

28

shared_ptr所有関係を表します。一方、意識weak_ptrを表します。複数のオブジェクトがお互いを所有しているということは、アーキテクチャに問題があることを意味します。この問題は、1 つ以上の独自の を を認識する(つまり、の) に変更することによって解決されます。weak_ptr

weak_ptr提案が役に立たないと見なされる理由がわかりません。

于 2009-04-22T11:49:06.033 に答える
21

循環参照を壊すために使用するようにはっきりと言われることに対するあなたの苛立ちを理解していますweak_ptr。循環参照は悪いプログラミングスタイルであると言われたとき、私はほとんど怒りを感じます。

具体的には、循環参照をどのように見つけますか。真実は、複雑なプロジェクトでは、いくつかの参照サイクルが間接的であり、見つけるのが難しいということです。

答えは、循環参照に対して脆弱なままにする誤った宣言を行うべきではないということです。私は真剣で、非常に人気のある慣行を批判しています-すべてにshared_ptrを盲目的に使用しています。

デザインでは、どのポインターが所有者で、どのポインターがオブザーバーであるかを明確にする必要があります。

所有者はを使用しますshared_ptr

オブザーバーが使用する場合weak_ptr-サイクルの一部であると思われるものだけでなく、それらすべて。

この方法に従うと、循環参照によって問題が発生することはなく、それらについて心配する必要はありません。もちろん、これらすべてを使用したいときに、これらすべてweak_ptrをsに変換するために作成するコードはたくさんあります。Boostは実際には仕事に任されていません。shared_ptr

于 2009-08-07T08:38:05.530 に答える
5

サイクルを検出するのはかなり簡単です。

  • カウントを大きな数値、たとえば1000に設定します(正確なサイズはアプリケーションによって異なります)
  • 興味のあるピオンターから始めて、そこからのポインターに従ってください
  • フォローするポインタごとに、カウントをデクリメントします
  • ポインタチェーンの最後に到達する前にカウントがゼロに低下した場合、サイクルがあります

ただし、あまり便利ではありません。また、参照カウントされたポインタのサイクルの問題を解決することは一般的に不可能です。そのため、世代の清掃などの代替のガベージコレクションスキームが発明されました。

于 2009-04-22T07:51:43.937 に答える
4

大きなUMLグラフを描画し、サイクルを探すよりもはるかに優れた方法は見つかりませんでした。

デバッグするには、次のように、レジストリに移動するインスタンスカウンターを使用します。

template <DWORD id>
class CDbgInstCount
{
public:
#ifdef _DEBUG
   CDbgInstCount()   { reghelper.Add(id, 1); }
   CDbgInstCount(CDbgInstCount const &) {  reghelper.Add(id, 1); }
   ~CDbgInstCount()  { reghelper.Add(id, -1); }
#else
#endif
};

問題のクラスにそれを追加し、レジストリを確認する必要があります。

(たとえば、「XYZ!」として指定されたIDは文字列に変換されます。残念ながら、テンプレートパラメータとして文字列定数を指定することはできません)

于 2009-04-22T07:55:19.340 に答える
2

boost::weak_ptrboost::shared_ptr多分の組み合わせ?この記事は興味深いかもしれません。

于 2009-04-22T08:27:28.467 に答える
1

サイクルを見つけるための一般的な解決策はここにあります:

リンクリストにサイクルがあるかどうかをテストするための最良のアルゴリズム

これは、リスト内のオブジェクトの構造を理解しており、各オブジェクトに含まれるすべてのポインターをたどることができることを前提としています。

于 2009-04-23T04:53:54.573 に答える
1

グラフ内の サイクルの検出に関するこの投稿を参照してください。

于 2009-04-22T14:09:51.873 に答える
-1

「weak_ptrはありません」と言ったのは知っていますが、どうしてですか?頭にweak_ptrを付けて尾を付け、weak_ptrを頭に付けて尾を付けると、サイクルが妨げられます。

于 2009-04-22T14:05:21.150 に答える