最終更新日時: 2025年10月14日 14時41分25秒 (JST)
Akira Takahashi が更新

履歴 編集

function
<memory>

# std::weak_ptr::lock(C++11)

    shared_ptr<T>
      lock() const noexcept; // (1) C++11
    constexpr shared_ptr<T>
      lock() const noexcept; // (1) C++26

## 概要

監視している`shared_ptr`オブジェクトを取得する。

## 戻り値

    expired() ? shared_ptr<T>() : shared_ptr<T>(*this)

監視している`shared_ptr`オブジェクトが有効な状態なら、その`shared_ptr`オブジェクトとリソースを共有する`shared_ptr`オブジェクトを作って返す。これによって、ロックしている間、`shared_ptr`オブジェクトの寿命が尽きないようにする。

監視している`shared_ptr`オブジェクトが寿命切れ状態なら、空の`shared_ptr`オブジェクトを作って返す。

- C++14 : 上記に相当することをアトミックに実行する。

## 備考

この関数が`shared_ptr`オブジェクトではなく生ポインタを返す設計になっていない理由を解説する。以下のコードを考えてみよう：

    std::shared_ptr<int> sp(new int(3));
    std::weak_ptr<int> wp = sp;

    // …この間に、spの寿命が切れるかもしれない…

    if (int* r = wp.lock()) {
      std::cout << *r << std::endl;
    }

このコードの場合、ロックを取得した`if`文内で、`shared_ptr`オブジェクト`sp`に対して`reset()`が呼ばれると、ポインタ`r`がダングリングポインタ(dangling pointer : 不正な領域を指すポインタ)になってしまう。

この関数が`shared_ptr`オブジェクトを返す設計になっていることで、ロック取得したポインタがダングリングポインタになってしまう問題を回避できる。

## 例外

投げない

## 例

    #include <iostream>
    #include <memory>

    int main()
    {
      std::shared_ptr<int> sp(new int(3));
      std::weak_ptr<int> wp = sp;

      // …この間に、spの寿命が切れるかもしれない…

      // wpが監視しているshared_ptrオブジェクトの
      // 寿命が切れていなければ処理する
      if (std::shared_ptr<int> r = wp.lock()) {
        std::cout << *r << std::endl;
      }
      else {
        // shared_ptrオブジェクトの寿命が切れている
        std::cout << "sp is expired" << std::endl;
      }
    }

### 出力

    3

## バージョン

### 言語

- C++11

### 処理系

- GCC: 4.3.6 ✅
- Clang: 3.0 ✅
- ICC: ?
- Visual C++: ?

## 参照

- LWG 2316 - weak_ptr::lock() should be atomic
- P3037R6 `constexpr std::shared_ptr` and friends