Использование std::unique_ptr

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

Здесь кажется, что p1 больше не является «уникальным», поскольку p2 также ссылается на него.

Это законно С++? Имеет ли unique_ptr copy_semantics? Если нет, и если он имеет только семантику перемещения, устанавливается ли p1 в NULL после назначения его p2?

ИЗМЕНИТЬ:

хорошо, значит правильная версия

 p2=std::move(p1)

В соответствии с этим после этого присваивания p1 недействителен? А разница с auto_ptr здесь есть? более безопасно явно указать передачу права собственности, чем неявно, как в случае с auto_ptr, я думаю


person Guillaume07    schedule 11.04.2011    source источник
comment
@Andres: Как человек, который обнаружил десятки ошибок в различных компиляторах C ++, я бы сказал, что это совсем не так, особенно когда речь идет об относительно новых (и относительно непроверенных) функциях языка, таких как ссылки rvalue.   -  person James McNellis    schedule 11.04.2011
comment
@James Это работает. :)   -  person Andres Jaan Tack    schedule 11.04.2011
comment
Вы можете посмотреть здесь типичное использование unique_ptr   -  person TiMoch    schedule 14.04.2013
comment
p1 содержит нулевой указатель после 'p2 = std::move(p1);'   -  person Quest    schedule 04.02.2014


Ответы (3)


std::unique_ptr нельзя назначать и копировать. Вам нужно использовать std::move();

so

p1 = std::move(p2);

Посмотрите здесь для получения дополнительной информации.

person Tony The Lion    schedule 11.04.2011
comment
Ссылка не работает. - person 0xC0DEFACE; 12.10.2016
comment
ссылка битая, не могу зайти - person snoopy; 17.10.2016

Вот статья, которую я написал, которая отвечает на ваши вопросы. Изначально я написал эту статью, чтобы представить эмуляцию 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 будет выполняться, часто присутствует ... неявно. Действительно, популярная реализация std::sort имела именно такую ​​логику в 1996 году, что и послужило причиной второго редизайна auto_ptr (который помог, но не решил проблему полностью).

person Howard Hinnant    schedule 11.04.2011
comment
Спасибо за статью :) В SO считается хорошей практикой суммировать содержание ссылки, чтобы ответ не потерял свою ценность, если ссылка перестанет работать. - person Matthieu M.; 11.04.2011

Согласно этому, p2=p1 является ошибкой компиляции.

person amit    schedule 11.04.2011