Namespaces
Variants

std::shared_ptr<T>:: reset

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
void reset ( ) noexcept ;
(1) (C++11以降)
template < class Y >
void reset ( Y * ptr ) ;
(2) (C++11以降)
template < class Y, class Deleter >
void reset ( Y * ptr, Deleter d ) ;
(3) (C++11以降)
template < class Y, class Deleter, class Alloc >
void reset ( Y * ptr, Deleter d, Alloc alloc ) ;
(4) (C++11以降)

管理対象オブジェクトを ptr が指すオブジェクトで置き換えます。オプションのデリータ d を指定でき、これは後で新しいオブジェクトを shared_ptr オブジェクトが所有しなくなったときに破棄するために使用されます。デフォルトでは、 delete 式がデリータとして使用されます。指定された型に対応する適切な delete 式が常に選択されます。これが、この関数が別個のパラメータ Y を使用するテンプレートとして実装されている理由です。

* this が既にオブジェクトを所有しており、それが最後の shared_ptr である場合、所有されているデリータを通じてオブジェクトは破棄されます。

ptr が指すオブジェクトが既に所有権を持たれている場合、この関数は一般に未定義動作を引き起こします。

1) 管理対象オブジェクトの所有権を解放する(存在する場合)。この呼び出し後、 * this は何もオブジェクトを管理しない。 shared_ptr ( ) . swap ( * this ) ; と等価。
2-4) 管理対象オブジェクトを ptr が指すオブジェクトで置き換えます。 Y は完全型であり、 T へ暗黙変換可能でなければなりません。さらに:
2) デリータとしてdelete式を使用します。有効なdelete式が利用可能でなければなりません。つまり、 delete ptr が適切に形成され、明確に定義された動作を持ち、例外を投げないことが必要です。以下と等価です: shared_ptr < T > ( ptr ) . swap ( * this ) ;
3) 指定されたデリータ d をデリータとして使用する。 Deleter は型 T に対して呼び出し可能でなければならない。すなわち、 d ( ptr ) は適切な形式であり、明確に定義された動作を持ち、例外を送出してはならない。 Deleter CopyConstructible でなければならず、そのコピーコンストラクタとデストラクタは例外を送出してはならない。以下と等価: shared_ptr < T > ( ptr, d ) . swap ( * this ) ;
4) (3) と同様だが、内部使用のためのデータ割り当てに alloc のコピーを追加で使用する。 Alloc Allocator でなければならない。コピーコンストラクタとデストラクタは例外を投げてはならない。 shared_ptr < T > ( ptr, d, alloc ) . swap ( * this ) ; と等価。

目次

パラメータ

ptr - 所有権を取得するオブジェクトへのポインタ
d - オブジェクト削除用に保存するデリーター
alloc - 内部割り当てに使用するアロケーター

戻り値

(なし)

例外

2) std::bad_alloc 必要な追加メモリを取得できなかった場合。その他のエラーに対しては実装定義の例外をスローする可能性があります。 delete ptr 例外が発生した場合に呼び出されます。
3,4) std::bad_alloc 必要な追加メモリを取得できなかった場合。その他のエラーに対しては実装定義の例外をスローする可能性があります。 d ( ptr ) 例外が発生した場合に呼び出されます。

#include <iostream>
#include <memory>
struct Foo
{
    Foo(int n = 0) noexcept : bar(n)
    {
        std::cout << "Foo::Foo(), bar = " << bar << " @ " << this << '\n';
    }
    ~Foo()
    {
        std::cout << "Foo::~Foo(), bar = " << bar << " @ " << this << '\n';
    }
    int getBar() const noexcept { return bar; }
private:
    int bar;
};
int main()
{
    std::cout << "1) 一意の所有権\n";
    {
        std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100);
        std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
                  << sptr.use_count() << '\n';
        // Fooの新しいインスタンスを渡さずにshared_ptrをリセットする。
        // この呼び出しの後、古いインスタンスは破棄されます。
        std::cout << "sptr.reset() を呼び出す...\n";
        sptr.reset(); // ここで Foo のデストラクタを呼び出す
        std::cout << "reset() 後: use_count() = " << sptr.use_count()
                  << ", sptr = " << sptr << '\n';
    }   // reset()で既に実行済みのため、Fooのデストラクタは呼び出されない。
    std::cout << "\n2) ユニーク所有権\n";
    {
        std::shared_ptr<Foo> sptr = std::make_shared<Foo>(200);
        std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
                  << sptr.use_count() << '\n';
        // shared_ptrをリセットし、Fooの新しいインスタンスを割り当てる。
        // この呼び出しの後、古いインスタンスは破棄されます。
        std::cout << "sptr.reset() を呼び出す...\n";
        sptr.reset(new Foo{222});
        std::cout << "reset() 後: use_count() = " << sptr.use_count()
                  << ", sptr = " << sptr << "\nスコープを抜けています...\n";
    }   // Fooのデストラクタを呼び出す。
    std::cout << "\n3) 複数の所有権\n";
    {
        std::shared_ptr<Foo> sptr1 = std::make_shared<Foo>(300);
        std::shared_ptr<Foo> sptr2 = sptr1;
        std::shared_ptr<Foo> sptr3 = sptr2;
        std::cout << "Foo::bar = " << sptr1->getBar() << ", use_count() = "
                  << sptr1.use_count() << '\n';
        // shared_ptr sptr1 をリセットし、Foo の新しいインスタンスを割り当てる。
        // 古いインスタンスは sptr2 と sptr3 の間で共有されたままになります。
        std::cout << "call sptr1.reset()...\n";
        sptr1.reset(new Foo{333});
        std::cout << "reset() 後:\n"
                  << "sptr1.use_count() = " << sptr1.use_count()
                  << ", sptr1 @ " << sptr1 << '\n'
                  << "sptr2.use_count() = " << sptr2.use_count()
                  << ", sptr2 @ " << sptr2 << '\n'
                  << "sptr3.use_count() = " << sptr3.use_count()
                  << ", sptr3 @ " << sptr3 << '\n'
                  << "スコープを抜けます...\n";
    }   // 以下の2つのデストラクタを呼び出す: 1) sptr1が所有するFooのデストラクタ,
        // 2) sptr2/sptr3間で共有されるFoo。
}

出力例:

1) 単一所有権
Foo::Foo(), bar = 100 @ 0x23c5040
Foo::bar = 100, use_count() = 1
sptr.reset()を呼び出し...
Foo::~Foo(), bar = 100 @ 0x23c5040
reset()後: use_count() = 0, sptr = 0
2) 単一所有権
Foo::Foo(), bar = 200 @ 0x23c5040
Foo::bar = 200, use_count() = 1
sptr.reset()を呼び出し...
Foo::Foo(), bar = 222 @ 0x23c5050
Foo::~Foo(), bar = 200 @ 0x23c5040
reset()後: use_count() = 1, sptr = 0x23c5050
スコープを抜ける...
Foo::~Foo(), bar = 222 @ 0x23c5050
3) 複数所有権
Foo::Foo(), bar = 300 @ 0x23c5080
Foo::bar = 300, use_count() = 3
sptr1.reset()を呼び出し...
Foo::Foo(), bar = 333 @ 0x23c5050
reset()後:
sptr1.use_count() = 1, sptr1 @ 0x23c5050
sptr2.use_count() = 2, sptr2 @ 0x23c5080
sptr3.use_count() = 2, sptr3 @ 0x23c5080
スコープを抜ける...
Foo::~Foo(), bar = 300 @ 0x23c5080
Foo::~Foo(), bar = 333 @ 0x23c5050

関連項目

新しい shared_ptr を構築する
(public member function)