Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's with unique_ptr::get() instead of &*?

I'm using unique_ptr to manage some resources for safe destruction in every circumstance, etc.

void do_something(BLOB* b);
unique_ptr<BLOB> b(new_BLOB(20));

Is &* much worse than get? e.g.

do_something(&*b);

or

do_someting(b.get());

both seem to work.

like image 401
Sam Liddicott Avatar asked Oct 30 '15 17:10

Sam Liddicott


People also ask

Why would you choose shared_ptr instead of unique_ptr?

In short: Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.

What is the use of unique_ptr in C++?

When to use unique_ptr? Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.

Do I need to delete unique_ptr?

An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.


2 Answers

The operator* of std::unique_ptr has undefined behavior if no memory is owned by the unique_ptr where as get() will return nullptr.

If the unique_ptr could ever be empty I would suggest using get() otherwise there is no difference.

like image 99
NathanOliver Avatar answered Oct 05 '22 14:10

NathanOliver


&*b is not necessarily equivalent to b.get(). In order to be sure to recieve a pointer to the managed object, you want to use get(). There are two reasons:

  • Calling operator* on a unique_ptr not managing any object is undefined behaviour
  • The managed object of type T may overload operator& and as such you may not recieve a valid pointer to T.

The standard defines the bevaiour of operator* of std::unique_ptr:

typename add_lvalue_reference<T>::type operator*() const;

  1. Requires: get() != nullptr

  2. Returns: *get()

Thus, applying operator* (from &*) is not allowed if get() returns nullptr.

You will get the return value of any overloaded operator& in the managed object if present. This can be circumvented by using std::addressof but the undefined behaviour problem persists.

std::unique_ptr<T>::get() will give you the address of the managed object or nullptr if no object is managed. It is safer to use get() and you have a predictable result.

like image 22
Pixelchemist Avatar answered Oct 05 '22 14:10

Pixelchemist