0
0
CppHow-ToBeginner · 3 min read

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::move to 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_ptr by value without std::move, causing compilation errors.
  • Passing std::unique_ptr by raw pointer and then deleting it manually, which breaks ownership rules.
  • Passing std::shared_ptr by 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::move to 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.