std::shared_ptr<T>::reset
From cppreference.com
< cpp | memory | shared ptr
| 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) 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 メンバ関数) |