Ownership & lifetimes

Core semantics7 standards

RAII, smart pointers, observer conventions, rule of zero.

RAII becomes systematic: unique_ptr is the default owner, shared_ptr/weak_ptr for shared graphs, rule of five for resource types — and rule of zero for everything else.

class Session {
  std::unique_ptr<Socket> sock_;      // owns
  Logger* log_ = nullptr;             // observes, never deletes
public:
  explicit Session(std::unique_ptr<Socket> s) : sock_(std::move(s)) {}
  // rule of zero: no dtor/copy/move written by hand
};

std::make_unique closes the gap: “never write naked new” becomes fully expressible, and exception-safety holes in argument evaluation disappear.

auto s = std::make_unique<Session>(connect(host));  // no raw new

The observer convention hardens: a raw pointer or reference means non-owning, period. shared_ptr<T[]> works, and weak_from_this arrives via enable_shared_from_this.

// API contract reads from the signature alone:
Widget* find(Id id);                     // may be null, not yours
Widget& at(Id id);                       // never null, not yours
std::unique_ptr<Widget> take(Id id);     // yours now

std::span and std::string_view give non-owning views a vocabulary, which sharpens ownership audits: anything that is not an owner should usually be a view or a plain pointer/reference.

void parse(std::span<const std::byte> frame);  // borrowed buffer
// lifetime rule: the span must not outlive the frame it views

std::out_ptr / std::inout_ptr bridge smart pointers to C-style T** factory APIs without the temporary-raw-pointer dance.

std::unique_ptr<AVFrame, FrameDeleter> f;
avcodec_receive_frame(ctx, std::out_ptr(f));   // adopts on success

std::indirect<T> and std::polymorphic<T> are value-semantic owners of heap objects: deep-copying, const-propagating, rule-of-zero friendly — the blessed pimpl/polymorphic-member building blocks.

class Doc {
  std::indirect<Impl> impl_;          // pimpl with real value semantics
  std::polymorphic<Shape> shape_;     // copies copy the dynamic type
};
C++29direction · not adopted

Direction only: lifetime-safety profiles and borrow-checking proposals (the “Safe C++” debate) target statically rejecting dangling views; nothing is adopted yet.

C++26 per the final working draft; C++29 rows are proposals and direction, not adopted features.