After this lesson, you will be able to: Apply RAII + smart pointers (unique_ptr, shared_ptr, weak_ptr) instead of raw new/delete.
If your modern C++ code has `new` or `delete`, you're probably writing a bug. RAII + smart pointers eliminate ~90% of memory errors that plague C.
Resource Acquisition Is Initialization. Tie every resource (memory, file, lock, socket) to an object whose destructor releases it. Scope exit → destructor runs → resource freed. Automatically. Even on exceptions. RAII is why C++ never needs `finally` blocks and why modern C++ is safer than C.
Three flavors. unique_ptr is the default; the others are rare.
#include <memory>// unique_ptr, sole ownership. Most common.std::unique_ptr<User> u = std::make_unique<User>("Alex", 30);u->birthday();// u goes out of scope → ~User() runs → memory freed. No leak possible.// Can't copy a unique_ptr, but can MOVE itstd::unique_ptr<User> u2 = std::move(u); // u is now nullptr// shared_ptr, reference-counted. Multiple owners.std::shared_ptr<Config> cfg = std::make_shared<Config>();std::shared_ptr<Config> cfg2 = cfg; // count = 2// last shared_ptr destroyed → memory freed// weak_ptr, non-owning observer to a shared_ptr. Breaks cycles.std::weak_ptr<Config> obs = cfg;if (auto locked = obs.lock()) { // safely promote to shared_ptr if alivelocked->use();}// NEVER do this in modern C++:// User* raw = new User("x", 1);// delete raw;
unique_ptr: ALWAYS the default. 95% of dynamic allocations want sole ownership. shared_ptr: use only when ownership genuinely shared (e.g., cached objects across threads). Has runtime cost (atomic refcount). weak_ptr: with shared_ptr to break ownership cycles (parent → child → parent). raw pointer (T*): non-owning observer. The function does NOT delete it. Like a reference but nullable.
RAII isn't just for memory.
#include <cstdio>#include <memory>// Wrap a C-style FILE* in a unique_ptr with custom deleterauto deleter = [](FILE* f) { if (f) std::fclose(f); };std::unique_ptr<FILE, decltype(deleter)> file(std::fopen("data.txt", "r"), deleter);if (file) {char buf[256];std::fgets(buf, sizeof(buf), file.get());// file auto-closes on scope exit, even if exception thrown}
shared_ptr cycles → memory leaks. Use weak_ptr to break. Passing raw `new T(...)` to a smart pointer (use `make_unique` / `make_shared`, exception-safe). Storing a raw pointer to a smart-pointer-owned object, then deleting it. Using shared_ptr by reflex, it's heavier than unique_ptr.
Sign in and purchase access to unlock this lesson.