C++ Tutorial · Memory and Pointers · Lesson 11 of 21
C++ Smart Pointers and RAII
unique_ptr, shared_ptr, RAII and why you rarely write new/delete.
RAII
RAII (Resource Acquisition Is Initialisation) is the heart of modern C++: an object acquires a resource in its constructor and releases it in its destructor, which runs automatically when the object goes out of scope — even if an exception is thrown:
#include <iostream>
#include <string>
class FileHandle {
public:
explicit FileHandle(std::string name) : name_(std::move(name)) {
std::cout << "open " << name_ << '\n';
}
~FileHandle() { std::cout << "close " << name_ << '\n'; }
private:
std::string name_;
};
int main() {
std::cout << "start\n";
{
FileHandle a("log.txt");
FileHandle b("data.csv");
std::cout << "using files\n";
} // destructors run here, in reverse order
std::cout << "end\n";
}
Output
start open log.txt open data.csv using files close data.csv close log.txt end
Run this on your computer — see “Get Started” for setup.
Smart pointers
Never manage heap memory with raw new/delete. Use:
std::unique_ptr<T>— single owner; freed automatically. Create withstd::make_unique.std::shared_ptr<T>— shared ownership with a reference count. Create withstd::make_shared.
#include <iostream>
#include <memory>
#include <string>
struct Widget {
std::string name;
explicit Widget(std::string n) : name(std::move(n)) {}
~Widget() { std::cout << "destroy " << name << '\n'; }
void draw() const { std::cout << "draw " << name << '\n'; }
};
int main() {
auto owner = std::make_unique<Widget>("button");
owner->draw();
auto moved = std::move(owner); // ownership transferred; owner is now null
std::cout << std::boolalpha << (owner == nullptr) << '\n';
auto shared = std::make_shared<Widget>("logo");
{
auto copy = shared;
std::cout << "owners: " << shared.use_count() << '\n';
}
std::cout << "owners: " << shared.use_count() << '\n';
}
Output
draw button true owners: 2 owners: 1 destroy logo destroy button
Run this on your computer — see “Get Started” for setup.
Test yourself
Which smart pointer has exactly one owner?
std::shared_ptrstd::unique_ptrstd::weak_ptrstd::auto_ptr
Show answer
Answer: std::unique_ptr