Sahaj.blogs
10 Jan 2024 · StudyPhase 2 · C++

C++ · Smart pointers

unique_ptr for single ownership, shared_ptr with reference counting, weak_ptr to break cycles, and make_unique/make_shared.

Smart pointers are RAII for heap memory. Modern C++ code almost never needs a raw delete.

  • std::unique_ptr<T>: one owner. It can be moved but not copied, and the object is freed when the owner goes away. Create one with std::make_unique<T>(...).
  • std::shared_ptr<T>: shared ownership through a reference count. The object is freed when the count drops to 0. This is close to how CPython manages objects.
  • std::weak_ptr<T>: observes a shared_ptr without owning it, which breaks reference cycles.

My default from now on: unique_ptr, switching to shared_ptr only when ownership is genuinely shared.

#include <iostream>
#include <memory>
#include <string>
#include <utility>

struct Model {
    std::string name;
    explicit Model(std::string n) : name(std::move(n)) { std::cout << "load " << name << '\n'; }
    ~Model() { std::cout << "free " << name << '\n'; }
};

int main() {
    auto a = std::make_unique<Model>("unique-model");
    auto b = std::move(a);                         // ownership moves
    std::cout << "a empty? " << (a == nullptr) << ", b owns " << b->name << '\n';

    std::weak_ptr<Model> watcher;
    {
        auto s1 = std::make_shared<Model>("shared-model");
        watcher = s1;
        {
            auto s2 = s1;
            std::cout << "use_count " << s1.use_count() << '\n';
        }
        std::cout << "use_count " << s1.use_count() << ", expired? " << watcher.expired() << '\n';
    }
    std::cout << "after scope, expired? " << watcher.expired() << '\n';
}

Output:

load unique-model
a empty? 1, b owns unique-model
load shared-model
use_count 2
use_count 1, expired? 0
free shared-model
after scope, expired? 1
free unique-model

#cpp#memory

Sources

  1. std::unique_ptr — cppreference.com
  2. std::shared_ptr — cppreference.com
  3. C++ Core Guidelines R.20: use unique_ptr or shared_ptr to represent ownership — Standard C++ Foundation