поведение конструктора std :: unique_ptr - PullRequest
4 голосов
/ 19 сентября 2019

Прежде всего, я знаю, что мы должны использовать std::make_unique() вместо вызова конструктора std::unique_ptr, и я знаю почему.

Но я смотрел документацию std::unique_ptr, чтобы скоротать времяи отточить мои знания об этом, и я нашел следующие примеры об использовании конструктора:

// unique_ptr constructor example
#include <iostream>
#include <memory>

int main () {
  std::default_delete<int> d;
  std::unique_ptr<int> u1;
  std::unique_ptr<int> u2 (nullptr);
  std::unique_ptr<int> u3 (new int);
  std::unique_ptr<int> u4 (new int, d);
  std::unique_ptr<int> u5 (new int, std::default_delete<int>());
  std::unique_ptr<int> u6 (std::move(u5));
  std::unique_ptr<int> u7 (std::move(u6));
  std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));

  std::cout << "u1: " << (u1?"not null":"null") << '\n';
  std::cout << "u2: " << (u2?"not null":"null") << '\n';
  std::cout << "u3: " << (u3?"not null":"null") << '\n';
  std::cout << "u4: " << (u4?"not null":"null") << '\n';
  std::cout << "u5: " << (u5?"not null":"null") << '\n';
  std::cout << "u6: " << (u6?"not null":"null") << '\n';
  std::cout << "u7: " << (u7?"not null":"null") << '\n';
  std::cout << "u8: " << (u8?"not null":"null") << '\n';

  return 0;
}

Он генерирует (и я подтвердил это, выполняя код) следующие результаты:

u1: нольu2: нольu3: не нольu4: не нольu5: нольu6: нольu7: не нольu8: не ноль

Я пытаюсь понять, что:

  • Почему u4 действителен, в то время как u5 недействителен (nullptr)?
  • Почему u7 допустимо, но не u6?

Возможно, эти вопросы очень простые, но я полностью упускаю суть.

Если кто-то можетпросветите меня по этим вопросам, я был бы признателен.

Ответы [ 3 ]

6 голосов
/ 19 сентября 2019

std::move назван move по причине.Когда вы переходите от одного std::unique_ptr к другому, тот, с которого вы переходите, становится nullptr.Иначе быть не могло, в конце концов, это уникальный ptr, и два экземпляра unique_ptr, совместно использующие одни и те же данные, нарушат это.(Также оба, выходящие из области видимости, дважды вызывали бы средство удаления, и тогда весь ад выпадал.)

5 голосов
/ 19 сентября 2019

Почему значение u4 допустимо, а u5 нет (nullptr)?

Поскольку u5 было перемещено из инициализации u6, а u4 не было перемещеноиз.Конструктор перемещения гарантированно установит перемещение от указателя к нулю.Он не может указывать на тот же объект, что и u6, поскольку это нарушит ограничение уникальности.

Почему u7 допустимо, но не u6?

По той же причине.

3 голосов
/ 19 сентября 2019

Перемещение объекта с уникальной собственностью означает, что у нового владельца он есть, а у предыдущего владельца ничего не осталось.
Очень похоже на то, как физические объекты работают в реальном мире.

Отсутствие ничего указывает на то, что владелец преобразовал в нулевой указатель.

Объект, который изначально принадлежал u5, был перемещен сначала в u6, а затем в u7.

...