名前空間
変種
操作

std::shared_ptr<T>::reset

From cppreference.com
< cpp‎ | memory‎ | shared ptr
 
 
メモリ管理ライブラリ
(説明用*)
未初期化メモリのアルゴリズム
(C++17)
(C++17)
(C++17)
制約付き未初期化
メモリアルゴリズム
Cライブラリ

アロケータ
メモリリソース
ガベージコレクションのサポート
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
(C++11)(C++23まで)
未初期化ストレージ
(C++20まで*)
(C++20まで*)
明示的な生存期間管理
 
 
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) は正常に形成され、明確に定義された動作を持ち、例外をスローしない必要があります。DeleterCopyConstructible でなければならず、そのコピーコンストラクタとデストラクタは例外をスローしてはなりません。これは shared_ptr<T>(ptr, d).swap(*this); に相当します。
4) (3) と同様ですが、内部使用のためのデータの確保に alloc のコピーをさらに使用します。AllocAllocator でなければなりません。コピーコンストラクタとデストラクタは例外をスローしてはなりません。これは 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) unique ownership\n";
    {
        std::shared_ptr<Foo> sptr = std::make_shared<Foo>(100);
 
        std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
                  << sptr.use_count() << '\n';
 
        // Reset the shared_ptr without handing it a fresh instance of Foo.
        // The old instance will be destroyed after this call.
        std::cout << "call sptr.reset()...\n";
        sptr.reset(); // calls Foo's destructor here
        std::cout << "After reset(): use_count() = " << sptr.use_count()
                  << ", sptr = " << sptr << '\n';
    }   // No call to Foo's destructor, it was done earlier in reset().
 
    std::cout << "\n2) unique ownership\n";
    {
        std::shared_ptr<Foo> sptr = std::make_shared<Foo>(200);
 
        std::cout << "Foo::bar = " << sptr->getBar() << ", use_count() = "
                  << sptr.use_count() << '\n';
 
        // Reset the shared_ptr, hand it a fresh instance of Foo.
        // The old instance will be destroyed after this call.
        std::cout << "call sptr.reset()...\n";
        sptr.reset(new Foo{222});
        std::cout << "After reset(): use_count() = " << sptr.use_count()
                  << ", sptr = " << sptr << "\nLeaving the scope...\n";
    }   // Calls Foo's destructor.
 
    std::cout << "\n3) multiple ownership\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';
 
        // Reset the shared_ptr sptr1, hand it a fresh instance of Foo.
        // The old instance will stay shared between sptr2 and sptr3.
        std::cout << "call sptr1.reset()...\n";
        sptr1.reset(new Foo{333});
 
        std::cout << "After 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'
                  << "Leaving the scope...\n";
    }   // Calls two destructors of: 1) Foo owned by sptr1,
        // 2) Foo shared between sptr2/sptr3.
}

実行結果の例

1) unique ownership
Foo::Foo(), bar = 100 @ 0x23c5040
Foo::bar = 100, use_count() = 1
call sptr.reset()...
Foo::~Foo(), bar = 100 @ 0x23c5040
After reset(): use_count() = 0, sptr = 0
 
2) unique ownership
Foo::Foo(), bar = 200 @ 0x23c5040
Foo::bar = 200, use_count() = 1
call sptr.reset()...
Foo::Foo(), bar = 222 @ 0x23c5050
Foo::~Foo(), bar = 200 @ 0x23c5040
After reset(): use_count() = 1, sptr = 0x23c5050
Leaving the scope...
Foo::~Foo(), bar = 222 @ 0x23c5050
 
3) multiple ownership
Foo::Foo(), bar = 300 @ 0x23c5080
Foo::bar = 300, use_count() = 3
call sptr1.reset()...
Foo::Foo(), bar = 333 @ 0x23c5050
After reset():
sptr1.use_count() = 1, sptr1 @ 0x23c5050
sptr2.use_count() = 2, sptr2 @ 0x23c5080
sptr3.use_count() = 2, sptr3 @ 0x23c5080
Leaving the scope...
Foo::~Foo(), bar = 300 @ 0x23c5080
Foo::~Foo(), bar = 333 @ 0x23c5050

[編集] 関連項目

新しい shared_ptr を構築する
(public メンバ関数) [編集]
English 日本語 中文(简体) 中文(繁體)