04 — Ownership, Raw Pointers, and Smart Pointers

04 — Ownership, Raw Pointers, and Smart Pointers

Core Idea

Modern C++ code should make ownership obvious.

Ownership means responsibility for destroying an object or releasing a resource.

Raw Pointers

Raw pointers are fine as non-owning references.

void print_user(const User* user) {
    if (user) {
        std::cout << user->name << '\n';
    }
}

But raw owning pointers are dangerous.

Avoid:

User* user = new User{}; // who deletes this?

References

Use references when the object must exist and cannot be null.

void print_user(const User& user) {
    std::cout << user.name << '\n';
}

std::unique_ptr

Use unique_ptr for exclusive ownership.

auto user = std::make_unique<User>("Ada");

Characteristics:

  • one owner,
  • movable,
  • not copyable,
  • deletes automatically.

Pass ownership:

void take_user(std::unique_ptr<User> user);

auto user = std::make_unique<User>();
take_user(std::move(user));

std::shared_ptr

Use shared_ptr only when ownership is genuinely shared.

auto user = std::make_shared<User>();

Characteristics:

  • reference counted,
  • copyable,
  • deletes when last owner dies,
  • has runtime overhead,
  • can create cycles.

std::weak_ptr

Use weak_ptr to observe a shared_ptr object without owning it.

std::weak_ptr<User> weak = shared;

if (auto user = weak.lock()) {
    // safe to use user
}

Choosing the Right Type

void read(const User& u);                 // must exist, no ownership
void maybe_read(const User* u);           // optional, no ownership
void take(std::unique_ptr<User> u);       // takes ownership
void share(std::shared_ptr<User> u);      // shares ownership

Common Mistakes

Overusing shared_ptr

Do not use shared_ptr just because it feels safe. Shared ownership makes lifetimes harder to reason about.

Calling delete Manually

If you use smart pointers correctly, you almost never call delete directly.

Returning Raw Owning Pointers

Avoid:

User* make_user();

Prefer:

std::unique_ptr<User> make_user();

Quick Self-Test

You should be able to answer:

  • Who owns this object?
  • Can this pointer be null?
  • Should this function take ownership?
  • Why is unique_ptr usually better than shared_ptr?
  • What problem does weak_ptr solve?

00 / The Agent

The chat box that lives on the blog.

running on Cloudflare · free tier

A tiny JS island posting to a Cloudflare Worker that streams answers from a free Nemotron endpoint. No origin server. No database. The static site stays static — this one box is the only thing that breathes.