- memory[meta header]
- std[meta namespace]
- shared_ptr[meta class]
- function[meta id-type]
- cpp11[meta cpp]
shared_ptr&
operator=(const shared_ptr& r) noexcept; // (1) C++11
constexpr shared_ptr&
operator=(const shared_ptr& r) noexcept; // (1) C++26
template <class Y>
shared_ptr&
operator=(const shared_ptr<Y>& r) noexcept; // (2) C++11
template <class Y>
constexpr shared_ptr&
operator=(const shared_ptr<Y>& r) noexcept; // (2) C++26
shared_ptr&
operator=(shared_ptr&& r) noexcept; // (3) C++11
constexpr shared_ptr&
operator=(shared_ptr&& r) noexcept; // (3) C++26
template <class Y>
shared_ptr&
operator=(shared_ptr<Y>&& r) noexcept; // (4) C++11
template <class Y>
constexpr shared_ptr&
operator=(shared_ptr<Y>&& r) noexcept; // (4) C++26
template <class Y>
shared_ptr&
operator=(auto_ptr<Y>&& r); // (5)
// C++11から非推奨
// C++17で削除
template <class Y, class D>
shared_ptr&
operator=(unique_ptr<Y, D>&& r); // (6) C++11
template <class Y, class D>
constexpr shared_ptr&
operator=(unique_ptr<Y, D>&& r); // (6) C++26- unique_ptr[link /reference/memory/unique_ptr.md]
- (1), (2) : 自身が保持しているリソースの所有権を放棄し、
rが持つリソースの所有権を共有する。 - (3), (4), (5), (6) : 自身が保持しているリソースの所有権を放棄し、
rが持つリソースの所有権を*thisに移動する。
- (1), (2) :
shared_ptr(r).swap(*this) - (3), (4) :
shared_ptr(std::move(r)).swap(*this) - (5) :
shared_ptr(r).swap(*this) - (6) :
shared_ptr(std::move(r)).swap(*this)
*this
- (1) : 投げない
- (2) : 投げない
- (3) : 投げない
- (4) : 投げない
#include <cassert>
#include <memory>
int main()
{
// (1)
// 自身の所有権を放棄し、
// 他のshared_ptrオブジェクトとリソースを共有する。
{
std::shared_ptr<int> p(new int(3));
std::shared_ptr<int> q;
q = p;
assert(*p.get() == 3);
assert(p.use_count() == 2);
assert(*q.get() == 3);
assert(q.use_count() == 2);
}
// (2)
// 自身の所有権を放棄し、
// 変換可能なshared_ptrオブジェクトとリソースを共有する。
{
std::shared_ptr<int> p(new int(3));
std::shared_ptr<void> q;
q = p;
assert(*p.get() == 3);
assert(p.use_count() == 2);
assert(*static_cast<int*>(q.get()) == 3);
assert(q.use_count() == 2);
}
// (3)
// 自身の所有権を放棄し、
// 他のshared_ptrから所有権を移動する
{
std::shared_ptr<int> p(new int(3));
std::shared_ptr<int> q;
q = std::move(p);
// 移動元は空の状態になる
assert(p.get() == nullptr);
assert(p.use_count() == 0);
assert(*q.get() == 3);
assert(q.use_count() == 1);
}
// (6)
// 自身の所有権を放棄し、
// unique_ptrオブジェクトから所有権を移動する
{
std::unique_ptr<int> p(new int(3));
std::shared_ptr<int> q;
q = std::move(p);
// 移動元は空の状態になる
assert(p.get() == nullptr);
assert(*q.get() == 3);
assert(q.use_count() == 1);
}
}- std::move[link /reference/utility/move.md]
- p.get()[link get.md]
- p.use_count()[link use_count.md]
- C++11
- GCC: 4.3.6(unique_ptr以外) [mark verified], 4.4.7 [mark verified]
- Clang: 3.0 [mark verified]
- ICC: ?
- Visual C++: 2008 (TR1) [mark verified], 2010 [mark verified], 2012 [mark verified], 2013 [mark verified]
- 2008は(1), (2), (5)変形のみ
- 2008, 2010の(5)は、仮引数の型が
auto_ptr<Y>&&ではなくauto_ptr<Y>&になっている。