モジュールのレッスン (2/2)
std::weak_ptr
std::shared_ptr は非常に便利ですが、共有所有権のみに依存すると、循環参照 (または循環依存関係) として知られる問題が発生する可能性があります。
2 つ以上のオブジェクトのそれぞれに、他方を指す shared_ptr が含まれている場合、閉じたループが作成されます。この状況では、どちらのオブジェクトの参照カウントもゼロにならないため、割り当て解除ができず、メモリ リークが発生します。
std::weak_ptr とは
所有権サイクルを断ち切るために、標準ライブラリは std::weak_ptr を提供します。これは、shared_ptr によって管理されるオブジェクトを監視するスマート ポインターですが、参照カウントは増加しません。
リソースを直接所有していないため、その破壊を防ぐことはできません。
#include <memory>
std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Does not increment reference count!リソースの確認とアクセス
weak_ptr はリソースを所有していないため、リソースはいつでも割り当て解除される可能性があります (関連するすべての shared_ptr インスタンスがスコープ外になった場合)。
監視されたリソースを使用するには、次のことを行う必要があります。
expired()を使用して、それがまだ有効かどうかを確認します。lock()メソッドを使用して、weak_ptrをshared_ptrに一時的に変換します。リソースがまだアクティブな場合、lock()は有効なshared_ptrを返します。それ以外の場合は、NULL ポインター (nullptr) を返します。
if (!weak.expired()) {
// lock() creates a temporary shared_ptr to ensure safe access
if (std::shared_ptr<int> sharedAccess = weak.lock()) {
std::cout << *sharedAccess << std::endl;
}
} else {
std::cout << "Resource deallocated!" << std::endl;
}自分で試してみてください
sPtr から初期化された wPtr という名前の std::weak_ptr<int> を宣言します。次に、std::cout を使用して、wPtr.expired() によって返されたブール値の結果を出力します。
ヒントを表示
同じジェネリック型 `<int>` を示す `weak_ptr` を宣言し、それに `sPtr` を直接割り当てます。
3 回の試行後に解決策が利用可能になります
wPtr で lock() メソッドを使用して、一時的なshared_ptrを取得します。操作が成功した場合 (ポインターが null でない場合)、逆参照された値を出力します。
ヒントを表示
「wPtr.lock()」を呼び出して「if」ブロック内の変数を初期化し、それをアスタリスク「*」で逆参照してリソースを出力します。
3 回の試行後に解決策が利用可能になります