How to Pass Smart Pointer to Function in C++
To pass a
std::unique_ptr to a function, pass it by std::move to transfer ownership or by raw pointer/reference to access without ownership. For std::shared_ptr, pass by value or const reference to share ownership safely.Syntax
Here are common ways to pass smart pointers to functions:
- Passing std::unique_ptr by value (transfer ownership): Use
std::moveto transfer ownership. - Passing std::unique_ptr by raw pointer or reference: Access without transferring ownership.
- Passing std::shared_ptr by value: Shares ownership and increments reference count.
- Passing std::shared_ptr by const reference: Avoids incrementing reference count but allows access.
cpp
void takeUniquePtr(std::unique_ptr<int> ptr); // ownership transfer void useUniquePtr(const std::unique_ptr<int>& ptr); // no ownership transfer void takeSharedPtr(std::shared_ptr<int> ptr); // shares ownership void useSharedPtr(const std::shared_ptr<int>& ptr); // no ownership transfer
Example
This example shows passing std::unique_ptr by moving ownership and passing std::shared_ptr by const reference.
cpp
#include <iostream> #include <memory> void takeUniquePtr(std::unique_ptr<int> ptr) { std::cout << "Unique pointer value: " << *ptr << std::endl; } void useSharedPtr(const std::shared_ptr<int>& ptr) { std::cout << "Shared pointer value: " << *ptr << std::endl; } int main() { std::unique_ptr<int> uPtr = std::make_unique<int>(10); takeUniquePtr(std::move(uPtr)); // ownership moved if (!uPtr) { std::cout << "uPtr is now null after move." << std::endl; } std::shared_ptr<int> sPtr = std::make_shared<int>(20); useSharedPtr(sPtr); // shared ownership std::cout << "Shared pointer use count: " << sPtr.use_count() << std::endl; return 0; }
Output
Unique pointer value: 10
uPtr is now null after move.
Shared pointer value: 20
Shared pointer use count: 1
Common Pitfalls
Common mistakes when passing smart pointers include:
- Passing
std::unique_ptrby value withoutstd::move, causing compilation errors. - Passing
std::unique_ptrby raw pointer and then deleting it manually, which breaks ownership rules. - Passing
std::shared_ptrby value unnecessarily, causing extra reference count increments and performance overhead.
cpp
#include <memory> // Wrong: Passing unique_ptr by value without move void wrongTake(std::unique_ptr<int> ptr) {} int main() { std::unique_ptr<int> uPtr = std::make_unique<int>(5); // wrongTake(uPtr); // Error: copy of unique_ptr not allowed wrongTake(std::move(uPtr)); // Correct: ownership transferred return 0; }
Quick Reference
Summary tips for passing smart pointers:
- std::unique_ptr: Pass by
std::moveto transfer ownership or by raw pointer/reference to access without ownership. - std::shared_ptr: Pass by const reference to avoid overhead or by value to share ownership.
- Avoid manual deletion of raw pointers obtained from smart pointers.
Key Takeaways
Use std::move to pass std::unique_ptr by value and transfer ownership.
Pass std::shared_ptr by const reference to avoid unnecessary reference count changes.
Never copy std::unique_ptr without std::move; it causes compilation errors.
Passing smart pointers by raw pointer or reference allows access without ownership transfer.
Avoid manual deletion of pointers managed by smart pointers to prevent errors.