std::shared_ptr<T>:: reset
|
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 が指すオブジェクトが既に所有権を持たれている場合、この関数は一般に未定義動作を引き起こします。
Y
は完全型であり、
T
へ暗黙変換可能でなければなりません。さらに:
Deleter
は型
T
に対して呼び出し可能でなければならない。すなわち、
d
(
ptr
)
は適切な形式であり、明確に定義された動作を持ち、例外を送出してはならない。
Deleter
は
CopyConstructible
でなければならず、そのコピーコンストラクタとデストラクタは例外を送出してはならない。以下と等価:
shared_ptr
<
T
>
(
ptr, d
)
.
swap
(
*
this
)
;
。
Alloc
は
Allocator
でなければならない。コピーコンストラクタとデストラクタは例外を投げてはならない。
shared_ptr
<
T
>
(
ptr, d, alloc
)
.
swap
(
*
this
)
;
と等価。
目次 |
パラメータ
| ptr | - | 所有権を取得するオブジェクトへのポインタ |
| d | - | オブジェクト削除用に保存するデリーター |
| alloc | - | 内部割り当てに使用するアロケーター |
戻り値
(なし)
例外
例
#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) |