Differences between `std::unique_ptr` and `std::weak_ptr`