Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::unique_ptr constructor behaviour

First of all, I know that we should use std::make_unique() instead of calling the std::unique_ptr constructor and I know why.

But I was looking at the documentation of std::unique_ptr to pass the time and sharpen my knowledge about it and I found the following examples about the constructor usage:

// 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;
}

It generates (and I verified it by executing the code) the following results:

u1: null
u2: null
u3: not null
u4: not null
u5: null
u6: null
u7: not null
u8: not null

What I'm struggling to understand is:

  • Why is u4 valid while u5 is not (nullptr) ?
  • Why is u7 valid but not u6 ?

Perhaps these questions are very basic but I'm completely missing the point.

If anyone could enlighten me about these questions, I would be grateful.

like image 322
Fareanor Avatar asked Dec 07 '22 11:12

Fareanor


1 Answers

std::move is named move for a reason. When you move from one std::unique_ptr to another, the one you move from becomes nullptr. It couldn't be any other way, it's a unique ptr after all, and two unique_ptr instances sharing the same data would violate that. (Also both going out of scope would call the deleter twice, and then all hell is loose.)

like image 60
Max Vollmer Avatar answered Dec 10 '22 00:12

Max Vollmer