boost::shared_ptr に関するブースト ドキュメントから:
実装は参照カウントを使用するため、shared_ptr インスタンスのサイクルは回収されません。たとえば、main() が A への shared_ptr を保持し、それが直接的または間接的に A への shared_ptr を保持している場合、A の使用回数は 2 になります。 「ブレイクサイクル」。
この段落が理解できませんでした。この状況の最小限の例を挙げて、その結果を説明していただけますか。
boost::shared_ptr に関するブースト ドキュメントから:
実装は参照カウントを使用するため、shared_ptr インスタンスのサイクルは回収されません。たとえば、main() が A への shared_ptr を保持し、それが直接的または間接的に A への shared_ptr を保持している場合、A の使用回数は 2 になります。 「ブレイクサイクル」。
この段落が理解できませんでした。この状況の最小限の例を挙げて、その結果を説明していただけますか。
スマート ポインターはどのように機能しますか? count
オブジェクトを指すスマート ポインターの を記憶し、count
新しい共有ポインターがオブジェクトの制御を取得するとこれを増加させcount
、共有ポインターがオブジェクトの制御を失うと を減少させます。
クラスがあるとします:
class A{
public:
A(){std::cout << "Object created" << std::endl;}
~A(){std::cout << "Object destroyed" << std::endl;}
void setSibling(boost::shared_ptr<A> &sibling){
m_sibling = sibling;
}
private:
boots::shared_ptr<A> m_sibling;
};
と foo():
void foo(){
//count increases from 0 to 1 (ptr take control on instance of A)
boost::shared_ptr<A> ptr(new A);
//count increases from 1 to 2 (m_sibling take control on instanse of A)
ptr->setSibling(ptr);
//count decreases from 2 to 1
//(ptr is destroyed and lose control on instance of A)
return;
}
~A() が呼び出されると、m_sibling は制御を失いますが、~A() が呼び出されるのは、すべての共有ポインタが制御を失う場合だけです。したがって、foo が呼び出された後は、A のそのインスタンスにアクセスできません。ただし、カウントは 1 であり、共有ポインターはそのオブジェクトを削除しないため、メモリとリソースのリークが発生します。
weak_ptr
in boost での使用方法については、in boostのドキュメントを参照してくださいshared_ptr
。
つまり、弱いポインターは共有ポインターに似ていますが、count
. 破棄されたオブジェクトから作成されたweak_ptrのインスタンスがある場合shared_ptr
、生のポインターにアクセスしようとすると、weak_prtインスタンスがスローされ、例外が発生します(segfaultは発生しません)。weak_prt
メソッドを使用して正しく使用する方法の例がブーストのドキュメントにありますweak_ptr::lock()
。
実装は参照カウントを使用するため、shared_ptr インスタンスのサイクルは回収されません。
あなたが書く:
この段落が理解できませんでした
それは良い; それはあなたが賢いからです。その段落はまったく意味がありません。あなたがそれを得ると思うなら、それはあなたがそうではないことを意味します.
循環依存関係があるため、循環を再利用することはできません。サイクルの残りの部分が回収される前に、サイクルのどの部分も回収することはできないため、破壊が始まる前にすべてのオブジェクトを破壊する必要があります。循環依存関係がある場合、これはプログラムの壊れた設計の一部です。スマート ポインター (または参照カウント) のせいにしないでください。
基本的な依存関係の問題のどの部分も、スマート ポインターの実装の詳細とはまったく関係がありません。これは、所有するスマート ポインターの定義そのものによって引き起こされます。所有されているオブジェクトは、(最後の) 所有しているポインターのデストラクタが実行を開始する前に破棄されません。
そしてもちろんstd::unique_ptr
、参照カウントさえも持たないような排他的所有権を持つスマート ポインターにも当てはまります。
「サイクルを壊す」には、weak_ptr を使用します。
しないでください。サイクルを避けてください。サイクルを「壊す」ことはできません。サイクルを「壊す」などということはありません。
Boost のドキュメントは、役に立たないよりも悪いです。危ないです。このようなレベルでインバリアントと実装が混在しており、スマート ポインターのセマンティックについて非常によく理解されていません。
そして、偽情報とアンチパターンが自己複製する能力について多くを語っています!