Home/C++/Ownership, smart pointers, and weak observers

Ownership, smart pointers, and weak observers

Exclusive transfer, shared lifetime and non-owning caches

unique_ptr<T> owns exactly one allocation and transfers ownership by move. shared_ptr<T> co-owns an allocation through a control block; copying it extends lifetime, but does not make T's mutable state thread-safe. A raw pointer is an observer, while weak_ptr is an observer that can test and safely acquire shared lifetime.

cpp
auto strong=std::make_shared<std::string>("resource");
std::weak_ptr<std::string> observer=strong;
auto borrowed_owner=observer.lock(); // one atomic lifetime acquisition

Do not call expired() and then assume a raw pointer remains alive: another owner may disappear between check and use. lock() combines the check and acquisition. Shared-pointer cycles retain each other even after outside owners vanish; choose weak back-links when a relationship must not own its parent. Avoid constructing two shared_ptr control blocks from the same raw pointer, which creates two independent deleters for one allocation.

A cache that stores shared_ptr retains resources forever until eviction. A weak cache permits reuse while some caller owns a resource, but does not itself prolong the resource lifetime. Expired weak entries may retain small control-block metadata until pruned; they do not retain the resource object. Identity is observable: acquiring the same live key should return the same allocation, while a key whose last owner vanished may produce a new allocation. Never assert the new address differs, because an allocator may reuse freed storage.

cpp
std::map<std::string,std::weak_ptr<Resource>> cache;
// Reacquire with lock(); create a fresh shared owner only when acquisition fails.

The exercise is sequential. Sharing control blocks across threads is supported, but concurrently mutating the same map still requires synchronization. Prefer explicit ownership in signatures: clone accepts a const reference and returns a new unique owner; acquire returns shared ownership.

Put it into practice

Implement the exercise in a full-screen workspace, then run its tests.

Open practice
Next lessonPolymorphism and composition