最終更新日時(UTC):
が更新

履歴 編集

function
<memory>

std::unique_ptr::コンストラクタ(C++11)

constexpr unique_ptr() noexcept;             // (1) 単一オブジェクト、配列

explicit unique_ptr(pointer p) noexcept;           // (2) 単一オブジェクト、配列(C++14まで)
constexpr explicit unique_ptr(pointer p) noexcept; // (2) 単一オブジェクト C++23
template<class U>
explicit unique_ptr(U p) noexcept;                 // (2) 配列 C++17
template<class U>
constexpr explicit unique_ptr(U p) noexcept;       // (2) 配列 C++23

unique_ptr(pointer p, const D& d1) noexcept;           // (3) 単一オブジェクト、配列(C++14まで)
constexpr unique_ptr(pointer p, const D& d1) noexcept; // (3) 単一オブジェクト C++23
template<class U>
unique_ptr(U p, const D& d1) noexcept;                 // (3) 配列 C++17
template<class U>
constexpr unique_ptr(U p, const D& d1) noexcept;       // (3) 配列 C++23

unique_ptr(pointer p, D&& d2) noexcept;           // (4) 単一オブジェクト、配列(C++14まで)
constexpr unique_ptr(pointer p, D&& d2) noexcept; // (4) 単一オブジェクト C++23
template<class U>
unique_ptr(U p, D&& d2) noexcept;                 // (4) 配列 C++17
template<class U>
constexpr unique_ptr(U p, D&& d2) noexcept;       // (4) 配列 C++23

unique_ptr(unique_ptr&& u) noexcept;           // (5) 単一オブジェクト、配列
constexpr unique_ptr(unique_ptr&& u) noexcept; // (5) 単一オブジェクト、配列 C++23

constexpr unique_ptr(nullptr_t) noexcept;    // (6) 単一オブジェクト、配列

template <class U, class E>
unique_ptr(unique_ptr<U, E>&& u) noexcept;   // (7) 単一オブジェクト、配列(C++17)
template <class U, class E>
constexpr unique_ptr(unique_ptr<U, E>&& u) noexcept; // (7) 単一オブジェクト、配列 C++23

template <class U>
unique_ptr(auto_ptr<U>&& u) noexcept;        // (8) 単一オブジェクト
                                             // C++11から非推奨
                                             // C++17で削除

unique_ptr(const unique_ptr&) = delete;      // (9) 単一オブジェクト、配列

unique_ptrオブジェクトの構築

  • (1) : デフォルトコンストラクタ。所有権を持たない、空のunique_ptrオブジェクトを構築する。
  • (2) : 生ポインタの所有権を受け取る。
  • (3), (4) : 生ポインタの所有権、およびデリータオブジェクトを受け取る。デリータオブジェクトはforwardされる。
  • (5) : ムーブコンストラクタ。uから*thisに、所有権を譲渡する。
  • (6) : デフォルトコンストラクタと同じく、所有権を持たない、空のunique_ptrオブジェクトを構築する。
  • (7) : 変換可能なポインタ型を持つunique_ptrオブジェクトからの変換。
  • (8) : 変換可能なポインタ型を持つauto_ptrオブジェクトからの変換。
  • (9) : コピー構築禁止。

要件

  • (1), (2) : デリータの型Dが、例外を投げずにデフォルト構築可能であること。
  • (3) : デリータの型Dが、例外を投げずにコピー構築可能であること。
  • (4), (5) : デリータの型Dが、例外を投げずにムーブ構築可能であること。
  • (6) : デリータの型Dが、例外を投げずにデフォルト構築可能であること。
  • (7) : 以下の条件を満たさない場合、この関数はオーバーロード解決の候補から外れる:
    • unique_ptr<U, E>::pointerが、pointerに暗黙変換可能な型であること。
    • Uが配列型ではないこと。
    • DEが同じ型であること。もしくは参照型ではないDにおいて、EDに暗黙的に変換可能な型であること。

C++17 共通

C++17 配列版

  • (2), (3), (4) : 以下のいずれかの場合にのみオーバーロード解決に参加する:
    • Uはメンバ型pointerと同じ型
    • pointerelement_type*と同じ型かつUは何らかのポインタ型V*であり、V(*)[]element_type(*)[]に変換可能である
    • Unullptr_tである((3), (4)のみ)
  • (7) : 以下の全ての条件を満たさない場合、この関数はオーバーロード解決の候補から外れる:
    • Uは配列型ではないこと
    • pointerelement_type*と同じ型
    • unique_ptr<U, E>::pointerunique_ptr<U, E>::element_type*と同じ型
    • unique_ptr<U, E>::element_type(*)[]element_type(*)[]に変換可能である
    • DEは同じ型で共に参照型である、もしくはDは参照型ではなくEDに暗黙変換可能である

効果

  • (1) : 値初期化したポインタとデリータオブジェクトを、メンバ変数に保持する。
  • (2) : ポインタp値初期化したデリータオブジェクトを、メンバ変数に保持する。
  • (3) : ポインタpとデリータオブジェクトd1を、メンバ変数に保持する。
  • (4) : ポインタpと、d2からムーブしたデリータオブジェクトd2を、メンバ変数に保持する。
  • (5) : uが持つポインタの所有権を、*thisに譲渡する。デリータオブジェクトは、可能であればムーブし、そうでなければコピーする。
  • (6) : (1)と同じく、値初期化したポインタとデリータオブジェクトを、メンバ変数に保持する。
  • (7) : (5)と同じく、uが持つポインタの所有権を、*thisに譲渡する。デリータオブジェクトは、可能であればムーブし、そうでなければコピーする。
  • (8) : u.release()の戻り値である所有権が放棄されたポインタと、値初期化したデリータオブジェクトを、メンバ変数に保持する。

例外

投げない

備考

  • (3) : デリータの型DD&のように左辺値参照の形式の場合、このコンストラクタのデリータパラメータはD&型となる。

D deleter;
unique_ptr<T, D&> p(new T(), deleter); // pはdeleterへの参照を保持する

#include <cassert>
#include <memory>

int main()
{
  // (1) デフォルト構築
  // 所有権を持たない、空のunique_ptrオブジェクトを構築する
  std::unique_ptr<int> p1;
  assert(!p1);

  // (2) 生ポインタから所有権を譲渡して構築
  std::unique_ptr<int> p2(new int(3));
  assert(p2);

  // (3), (4) 生ポインタから所有権を譲渡し、デリータオブジェクトとともに構築
  std::unique_ptr<int> p3(new int(3), std::default_delete<int>());
  assert(p3);

  // (5) 他のunique_ptrから所有権を譲渡する
  std::unique_ptr<int> p5 = std::move(p3);
  assert(*p5 == 3);

  // (6) nullptrで構築
  // デフォルトコンストラクタ(1)と同じ
  std::unique_ptr<int> p6 = nullptr;
  assert(!p6);

  // (7) 変換可能な他のunique_ptrから所有権を譲渡する
  std::unique_ptr<const int> p7 = std::move(p5);
  assert(*static_cast<const int*>(p7.get()) == 3);
}

出力

バージョン

言語

  • C++11

処理系

  • GCC: 4.4.7 (nullptr_tのオーバーロード以外), 4.6.4
  • Clang: 3.0
  • ICC: ?
  • Visual C++: 2010, 2012, 2013
    • 2012までは、delete宣言に対応していないため、代わりにprivateで宣言のみ行う手法で代用されている。

関連項目

参照