In C++, std::unique_ptr is a smart pointer that owns the object it points to and guarantees exclusive ownership of the object. This means that std::unique_ptr cannot be copied to another std::unique_ptr and can only be moved, which is why it is called 'unique'. There are several ways to pass std::unique_ptr to a function:
1. Moving std::unique_ptr to a Function
When you want the function to take ownership of the object managed by std::unique_ptr, you can pass it to the function using move semantics. This is typically used when the function needs to own or consume the smart pointer.
cppvoid processResource(std::unique_ptr<Resource> res) { // Here, res now owns the ownership of the raw pointer res->doSomething(); // res automatically releases the resource when the function ends } int main() { std::unique_ptr<Resource> resource = std::make_unique<Resource>(); processResource(std::move(resource)); // Note the use of std::move, as std::unique_ptr cannot be copied // resource is now empty, and ownership has been transferred to processResource }
In this approach, after processing the resource, the caller can no longer access the original resource because the ownership of std::unique_ptr has been transferred.
2. Passing a Reference to std::unique_ptr
If the function only needs to operate on the object held by the smart pointer without owning it, you can pass a reference to std::unique_ptr.
cppvoid useResource(const std::unique_ptr<Resource>& resource) { // Use the resource without owning it resource->doSomething(); } int main() { std::unique_ptr<Resource> resource = std::make_unique<Resource>(); useResource(resource); // resource remains valid, and ownership stays with main }
This approach is suitable for scenarios where ownership transfer is not needed, and only access or operation on the resource is required.
3. Passing a Raw Pointer
If the function only needs to access the resource without caring about ownership and lifecycle management, you can pass a raw pointer to the object managed by std::unique_ptr.
cppvoid inspectResource(Resource* resource) { // Inspect the resource without modifying ownership resource->doSomething(); } int main() { std::unique_ptr<Resource> resource = std::make_unique<Resource>(); inspectResource(resource.get()); // Use get() to obtain the raw pointer // resource remains valid, and ownership stays with main }
This approach is suitable for cases where ownership does not need to be changed and only temporary access to the resource is required.
When designing interfaces and functions, choosing the appropriate way to pass std::unique_ptr is crucial, depending on how you wish to manage resource ownership and lifecycle.