Перекрыть необработанный указатель в unique_ptr и снова назначить его на unique_ptr - PullRequest
1 голос
/ 17 февраля 2020

Пожалуйста, дайте мне знать, какой конструктор unique_ptr вызывается ниже и почему? .. Я предполагаю, что здесь вызывается «конструктор перемещения», но я немного запутался в том, как его можно вызвать, в качестве аргумента для конструктора перемещения. требует 'r value reference', но ее я не использую никакие r-значения.

int* func1()
{
   int* p = new int();
   *p = 20;
   return p;
}

int main()
{
   std::unique_ptr<int> p = std::unique_ptr<int>(func1());
   return 0;
}

1 Ответ

2 голосов
/ 17 февраля 2020

Этот код не вызывает конструктор перемещения std::unique_ptr. Он вызывает конкретную c версию конструктора, в которой unique_ptr<T> создается из T*.

В документации конструктора std::unique_ptr это номер дела (2) (pointer - псевдоним для T*, поэтому в нашем случае int*)

Конструктор перемещения можно вызывать только со ссылкой на r-значение экземпляра того же класса. Это означает, что std::unique_ptr<int> может быть сконструирован с помощью перемещения, только передав ему std::unique_ptr<int>&&.

Вот пример кода, который вызывает конструктор перемещения с использованием возвращаемого значения из функции.

std::unique_ptr<int> func() {
    return std::unique_ptr<int>(new int);
}

int main() {
   std::unique_ptr<int> my_ptr(func()); // Move-constructor called here
   return 0
}

В другом примере будет использоваться std::move

int main() {
   std::unique_ptr<int> ptr1 = std::make_unique<int>(20);
   std::unique_ptr<int> ptr2 (std::move(ptr1)); // Move constructor called here

   // At this point ptr1 has been moved from and is now nullptr
   std::cout << ptr1.get() << " " <<ptr2.get()<< " " << *ptr2 <<std::endl;
   return 0
}

Вы можете видеть это Run Live здесь . Он напечатает 0, адрес p2 и 20.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...