web-dev-qa-db-ja.com

std :: unique_ptrの使用

std::unique_ptr<int> p1(new int);
std::unique_ptr<int> p2(new int);
p2=p1;

ここでは、p2がp1も参照しているため、p1はもはや「一意」ではないようです。

それは合法的なC++ですか? unique_ptrにはcopy_semanticsがありますか?いいえ、移動セマンティクスのみの場合、p1をp2に割り当てた後にNULLに設定されますか?

編集:

正しいバージョンは

 p2=std::move(p1)

それによると、この割り当ての後、p1は無効ですか?そして、auto_ptrとの違いはここにありますか? auto_ptrの場合のように、暗黙的にではなく、明示的に所有権の譲渡を指定する方が安全です

41
Guillaume07

std :: unique_ptrは、割り当てもコピーもできません。 std :: move();を使用する必要があります。

そう

p1 = std::move(p2);

詳しくは こちら をご覧ください。

67
Tony The Lion

ここにあなたの質問に答える私が書いた記事があります。私はもともと、unique_ptrのエミュレーションを提示するためにこの記事を書きました。ただし、エミュレーションに関する最初の数段落を無視して、「基本的な例」から読み始めることができます。

http://howardhinnant.github.io/unique_ptr03.html

編集:

上記のリンクされた記事を、この形式で実用的な答えを出すのに十分な小さなものに蒸留するのに苦労しました。しかし、ここに私の最高のショットがあります:

理由:汎用コードの安全性。 auto_ptrまたはunique_ptrのコピーを実際に作成することはできません。考慮してください:

template <class T>
void foo(T t)
{
    T copy_of_t = t;  // line 4
    assert(copy_of_t == t);
}

汎用コードが上記のfooのように見えることはまったく珍しいことではありません。 assertは実際には存在しない可能性がありますが、assertが頻繁に保持されるという仮定は...implicitlyです。確かに、std::sortの一般的な実装は、1996年にまさにこのロジックを持っていました。これは、2回目のauto_ptr再設計を促したものです。

12
Howard Hinnant

thisp2=p1はコンパイルエラーです。

3
amit