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?
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With