Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I assign or reset a unique_ptr?

Given the common situation where the lifespan of an owned object is linked to its owner, I can use a unique pointer one of 2 ways . .

It can be assigned:

class owner
{
    std::unique_ptr<someObject> owned;    
public:
    owner()
    {
        owned=std::unique_ptr<someObject>(new someObject());        
    }
};

The reset method can be utilised:

class owner
{
    std::unique_ptr<someObject> owned;    
public:
    owner()
    {
        owned.reset(new someObject());
    }
};

In the interests of best practice, should I prefer one form over the other?

EDIT: Sorry folks. I over simplified this. The heap allocation occurs in an initialise method and not in the ctor. Therefore, I cannot use initialiser lists.

like image 543
learnvst Avatar asked Apr 17 '13 13:04

learnvst


People also ask

What does unique_ptr Reset do?

std::unique_ptr::resetDestroys the object currently managed by the unique_ptr (if any) and takes ownership of p. If p is a null pointer (such as a default-initialized pointer), the unique_ptr becomes empty, managing no object after the call.

Do you need to delete a 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.

What happens when you move a unique_ptr?

A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it.


2 Answers

From the docs of unique_ptr's operator=:

Transfers ownership of the object pointed to by r to *this as if by calling reset(r.release()) followed by an assignment from std::forward<E>(r.get_deleter()).

And all you need of that is the reset call, so it's simpler to just call it directly

like image 171
Kos Avatar answered Oct 17 '22 22:10

Kos


The proper way to do this (that you didn't list) is to use the constructor of owned:

owner() : owned(new someObject())
{}

Apart from that I'd prefer reset as you don't create a useless intermediate instance in that case (even though there might be no difference on the machine level as the optimizer can do a lot there).

like image 32
filmor Avatar answered Oct 17 '22 23:10

filmor