Namespaces
Variants

std::unique_ptr<T,Deleter>:: unique_ptr

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(注:指定されたHTML要素には翻訳対象のテキストコンテンツが含まれていないため、構造は完全に保持されたままです)
プライマリテンプレート unique_ptr<T> のメンバー
constexpr unique_ptr ( ) noexcept ;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ;
(1)
explicit unique_ptr ( pointer p ) noexcept ;
(2) (C++23以降 constexpr)
unique_ptr ( pointer p, /* 下記参照 */ d1 ) noexcept ;
(3) (constexpr since C++23)
unique_ptr ( pointer p, /* 下記参照 */ d2 ) noexcept ;
(4) (constexpr since C++23)
unique_ptr ( unique_ptr && u ) noexcept ;
(5) (constexpr since C++23)
template < class U, class E >
unique_ptr ( unique_ptr < U, E > && u ) noexcept ;
(6) (constexpr since C++23)
unique_ptr ( const unique_ptr & ) = delete ;
(7)
template < class U >
unique_ptr ( std:: auto_ptr < U > && u ) noexcept ;
(8) (C++17で削除)
配列用特殊化のメンバー、unique_ptr<T[]>
constexpr unique_ptr ( ) noexcept ;
constexpr unique_ptr ( std:: nullptr_t ) noexcept ;
(1)
template < class U >
explicit unique_ptr ( U p ) noexcept ;
(2) (constexpr since C++23)
template < class U >
unique_ptr ( U p, /* 詳細は下記参照 */ d1 ) noexcept ;
(3) (constexpr C++23以降)
template < class U >
unique_ptr ( U p, /* 詳細は下記参照 */ d2 ) noexcept ;
(4) (constexpr C++23以降)
unique_ptr ( unique_ptr && u ) noexcept ;
(5) (C++23以降 constexpr)
template < class U, class E >
unique_ptr ( unique_ptr < U, E > && u ) noexcept ;
(6) (constexpr since C++23)
unique_ptr ( const unique_ptr & ) = delete ;
(7)
1) 何も所有しない std::unique_ptr を構築する。格納されたポインタと格納されたデリータを値初期化する。 Deleter DefaultConstructible であり、構築が例外を投げないことを要求する。これらのオーバーロードは、 std:: is_default_constructible < Deleter > :: value true であり、かつ Deleter がポインタ型でない場合にのみ、オーバーロード解決に参加する。
2) std::unique_ptr を構築し、所有するポインタを p で初期化し、デリータを値初期化します。 Deleter DefaultConstructible であり、構築が例外を投げないことを要求します。このオーバーロードは、 std:: is_default_constructible < Deleter > :: value true であり、かつ Deleter がポインタ型でない場合にのみ、オーバーロード解決に参加します。

このコンストラクタは クラステンプレート引数推論 によって選択されません。

(C++17以降)
3,4) std::unique_ptr オブジェクトを構築し、格納されたポインタを p で初期化し、下記のようにデリーター D を初期化する( D が参照型かどうかに依存する)。
a) D が非参照型 A の場合、シグネチャは以下の通り:
unique_ptr ( pointer p, const A & d ) noexcept ;
(1) ( Deleter がnothrow- CopyConstructible であることを要求)
unique_ptr ( pointer p, A && d ) noexcept ;
(2) ( Deleter がnothrow- MoveConstructible であることを要求)
b) D が左辺値参照型 A & の場合、シグネチャは以下の通り:
unique_ptr ( pointer p, A & d ) noexcept ;
(1)
unique_ptr ( pointer p, A && d ) = delete ;
(2)
c) D が左辺値参照型 const A & である場合、シグネチャは以下の通りです:
unique_ptr ( pointer p, const A & d ) noexcept ;
(1)
unique_ptr ( pointer p, const A && d ) = delete ;
(2)
すべての場合において、デリーターは std:: forward < decltype ( d ) > ( d ) から初期化されます。これらのオーバーロードは、 std:: is_constructible < D, decltype ( d ) > :: value true である場合にのみ、オーバーロード解決に参加します。

これら2つのコンストラクタは クラステンプレート引数推論 によって選択されません。

(C++17以降)
2-4) 配列に対する特殊化では、プライマリテンプレートのポインタパラメータを取るコンストラクタと同じように動作しますが、以下のいずれかの条件が真である場合に限り、オーバーロード解決に参加しないという追加の動作があります:
  • U pointer と同じ型である場合、または
  • U std::nullptr_t である場合、または
  • pointer element_type* と同じ型であり、かつ U が何らかのポインタ型 V* であり、 V(*)[] element_type(*)[] に暗黙的に変換可能である場合。
5) u からの所有権を * this に転送し、 u にヌルポインタを格納することで unique_ptr を構築する。このコンストラクタは、 std:: is_move_constructible < Deleter > :: value true の場合にのみオーバーロード解決に参加する。 Deleter が参照型でない場合、nothrow- MoveConstructible であることを要求する( Deleter が参照の場合、ムーブ構築後の get_deleter() u.get_deleter() は同じ値を参照する)。
6) unique_ptr を構築し、所有権を u から * this に転送します。ここで u は指定されたデリータ( E )で構築されます。 E が参照型かどうかに応じて、以下のように動作します:
a) if E が参照型の場合、このデリータは u のデリータからコピー構築される(この構築が例外を投げないことが要求される)、
b) もし E が非参照型の場合、このデリーターは u のデリーターからムーブ構築されます(この構築が例外を投げないことが要求されます)。
このコンストラクタは、以下のすべての条件が満たされる場合にのみオーバーロード解決に参加します:
a) unique_ptr < U, E > :: pointer pointer に暗黙的に変換可能です。
b) Uは配列型ではありません、
c) Deleter が参照型であり、かつ E Deleter と同じ型であるか、または Deleter が参照型ではなく、かつ E Deleter に暗黙的に変換可能であること。
6) 配列に対する特殊化は、以下のすべての条件が満たされる場合にのみオーバーロード解決に参加することを除き、プライマリテンプレートと同じように動作します:
  • U が配列型であること、
  • pointer element_type* と同じ型であること、
  • unique_ptr < U,E > :: pointer unique_ptr < U,E > :: element_type * と同じ型であること、
  • unique_ptr < U,E > :: element_type ( * ) [ ] element_type(*)[] に変換可能であること、
  • Deleter が参照型であり E Deleter と同じ型であるか、または Deleter が参照型ではなく E Deleter に暗黙的に変換可能であること。
7) コピーコンストラクタは明示的に削除されています。
8) 格納されたポインタが u.release() で初期化され、格納されたデリーターが値初期化された unique_ptr を構築する。このコンストラクタは、 U* T* に暗黙的に変換可能であり、かつ Deleter std:: default_delete < T > と同じ型である場合にのみ、オーバーロード解決に参加する。

目次

翻訳の説明: - 「Contents」を「目次」に翻訳しました - HTMLタグ、属性、数値はそのまま保持しています - C++関連の用語(Parameters、Notes、Example、Defect reports)は翻訳せずに原文のまま保持しています - すべての書式設定と構造を完全に維持しています

パラメータ

p - 管理対象オブジェクトへのポインタ
d1, d2 - オブジェクト破棄に使用するデリーター
u - 所有権を取得する別のスマートポインタ

注記

オーバーロード (2) をnewと共に使用する代わりに、 std::make_unique<T> を使用することが多くの場合より良い選択です。

(C++14以降)

std:: unique_ptr < Derived > はオーバーロード (6) を通じて std:: unique_ptr < Base > に暗黙的に変換可能です(管理対象ポインタと std::default_delete の両方が暗黙的に変換可能であるため)。

デフォルトコンストラクタは constexpr であるため、static unique_ptrsは 静的non-local初期化 の一部として初期化され、動的non-local初期化が開始される前に処理されます。これにより、任意の静的オブジェクトのコンストラクタ内でunique_ptrを安全に使用できます。

ポインタ型からの class template argument deduction は存在しません。これは、 new の配列形式と非配列形式から得られたポインタを区別することが不可能であるためです。

(C++17以降)

#include <iostream>
#include <memory>
struct Foo // 管理するオブジェクト
{
    Foo() { std::cout << "Foo コンストラクタ\n"; }
    Foo(const Foo&) { std::cout << "Foo コピーコンストラクタ\n"; }
    Foo(Foo&&) { std::cout << "Foo ムーブコンストラクタ\n"; }
    ~Foo() { std::cout << "~Foo デストラクタ\n"; }
};
struct D // deleter
{
    D() {};
    D(const D&) { std::cout << "D コピーコンストラクタ\n"; }
    D(D&) { std::cout << "D 非constコピーコンストラクタ\n"; }
    D(D&&) { std::cout << "D move ctor \n"; }
    void operator()(Foo* p) const
    {
        std::cout << "DはFooを削除しています\n";
        delete p;
    };
};
int main()
{
    std::cout << "Example constructor(1)...\n";
    std::unique_ptr<Foo> up1; // up1 は空です
    std::unique_ptr<Foo> up1b(nullptr); // up1b は空です
    std::cout << "Example constructor(2)...\n";
    {
        std::unique_ptr<Foo> up2(new Foo); //up2 は Foo を所有する
    } // Foo deleted
    std::cout << "Example constructor(3)...\n";
    D d;
    {   // deleter型は参照ではない
        std::unique_ptr<Foo, D> up3(new Foo, d); // デリーターがコピーされました
    }
    {   // deleter型は参照です
        std::unique_ptr<Foo, D&> up3b(new Foo, d); // up3b は d への参照を保持する
    }
    std::cout << "Example constructor(4)...\n";
    {   // deleter は参照ではない
        std::unique_ptr<Foo, D> up4(new Foo, D()); // deleter moved
    }
    std::cout << "Example constructor(5)...\n";
    {
        std::unique_ptr<Foo> up5a(new Foo);
        std::unique_ptr<Foo> up5b(std::move(up5a)); // 所有権の移転
    }
    std::cout << "Example constructor(6)...\n";
    {
        std::unique_ptr<Foo, D> up6a(new Foo, d); // D はコピーされる
        std::unique_ptr<Foo, D> up6b(std::move(up6a)); // D は移動されました
        std::unique_ptr<Foo, D&> up6c(new Foo, d); // D は参照です
        std::unique_ptr<Foo, D> up6d(std::move(up6c)); // D はコピーされる
    }
#if (__cplusplus < 201703L)
    std::cout << "Example constructor(7)...\n";
    {
        std::auto_ptr
(注:元のテキストはHTMLタグとC++固有の用語(std::auto_ptr)を含んでいるため、翻訳対象外です。表示されるテキスト部分が存在しないため、翻訳結果は元のHTML構造をそのまま保持しています)<Foo> up7a(new Foo);
        std::unique_ptr<Foo> up7b(std::move(up7a)); // 所有権の移転
    }
#endif
    std::cout << "例示配列コンストラクタ...\n";
    {
        std::unique_ptr<Foo[]> up(new Foo[3]
(注:元のテキストは閉じ括弧のみのため、日本語でも同じ記号を保持します));
    } // 3つのFooオブジェクトが削除されました
}

出力:

コンストラクタ例(1)...
コンストラクタ例(2)...
Foo コンストラクタ
~Foo デストラクタ
コンストラクタ例(3)...
Foo コンストラクタ
D コピーコンストラクタ
D が Foo を削除中
~Foo デストラクタ
Foo コンストラクタ
D が Foo を削除中
~Foo デストラクタ
コンストラクタ例(4)...
Foo コンストラクタ
D ムーブコンストラクタ
D が Foo を削除中
~Foo デストラクタ
コンストラクタ例(5)...
Foo コンストラクタ
~Foo デストラクタ
コンストラクタ例(6)...
Foo コンストラクタ
D コピーコンストラクタ
D ムーブコンストラクタ
Foo コンストラクタ
D 非constコピーコンストラクタ
D が Foo を削除中
~Foo デストラクタ
D が Foo を削除中
~Foo デストラクタ
コンストラクタ例(7)...
Foo コンストラクタ
~Foo デストラクタ
配列コンストラクタ例...
Foo コンストラクタ
Foo コンストラクタ
Foo コンストラクタ
~Foo デストラクタ
~Foo デストラクタ
~Foo デストラクタ

不具合報告

以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。

DR 適用対象 公開時の動作 修正後の動作
LWG 2118 C++11 unique_ptr<T[]> のコンストラクタが修飾変換を拒否していた。 受け入れる。
LWG 2520 C++11 unique_ptr<T[]> が誤って nullptr_t からの構築不可能になっていた。 構築可能に修正。
LWG 2801 C++11 デフォルトコンストラクタが制約されていなかった。 制約を追加。
LWG 2899 C++11 ムーブコンストラクタが制約されていなかった。 制約を追加。
LWG 2905 C++11 ポインタとデリーターからのコンストラクタの制約が誤っていた。 修正。
LWG 2944 C++11 一部の事前条件がLWG 2905によって誤って削除されていた。 復元。