Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::unique_ptr::release() vs std::move()

Tags:

c++

c++11

I have a class that represents a runtime context and builds a tree, the tree root is held in a unique_ptr. When building the tree is done I want to extract the tree. This is how it looks (not runnable, this is not a debugging question):

class Context {
    private:
    std::unique_ptr<Node> root{new Node{}};
    public:
    // imagine a constructor, attributes and methods to build a tree
    std::unique_ptr<Node> extractTree() {
        return std::move(this->root);
    }
};

So I used std::move() to extract the root node from the Context instance.

However there are alternatives to using std::move() e.g.:

std::unique_ptr<Node> extractTree() {
    // This seems less intuitive to me
    return std::unique_ptr<Node>{this->root.release()};
}

Is std::move() the best choice?

like image 500
kamikaze Avatar asked Mar 16 '16 08:03

kamikaze


People also ask

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. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.

What is unique_ ptr's release method for?

unique_ptr::releaseReleases the ownership of the managed object, if any. get() returns nullptr after the call. The caller is responsible for deleting the object.

What is std :: unique_ptr?

std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.


1 Answers

You should definitely go with the first version as the second one basically does the everything the first version does with more code and less readability.

Philosophically speaking, the second version moves the unique pointer, no more, no less. so why going around the table instead of using the already existing, more readable and more idiomatic std::unique_ptr(std::unique_ptr&&) ?

And lastly, if your smart pointer somewhere in the future will hold custom deleter , the first version will make sure the deleter moves as well, the second version does not moves the deleter. I can definitely imagine a programmer building non-custom deleter unique pointer out of custom-deleter unique_pointer with using release. With move semantics, the program will fail to compile.

like image 61
David Haim Avatar answered Sep 27 '22 18:09

David Haim